中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

jdbc關于實現Mybatis結果集解析

發布時間:2020-06-19 19:48:43 來源:網絡 閱讀:331 作者:nineteens 欄目:編程語言

  Jdbc 比較繁瑣的一個操作就是解析結果集ResultSet, 在實際開發時, 通常會將對結果集的解析封裝為一個工具類. 需要注意的時, jdbc查詢出來的屬性可能不能直接轉換為java的類型, 比如說java.sql.Date, 不能直接轉換為java.util.Date 或LocalDate等類型, 需要自定義轉換器. 如果比較熟悉Mybatis的話, 會發現Mybatis底層也封裝了大量的類型轉換器.

  1. 工具類源碼

  筆者的工具類比較簡單, 只封裝了三個方法:

  方法簽名  方法描述  參數說明

  public static LinkedHashMap toPropertyMap(ResultSet resultSet) throws SQLException  轉換單行結果集為Map結構. key為列別名, value為列值  resultSet: 查詢結果集

  public static T toBean(ResultSet resultSet, Class clz)  轉換結果集為單行對象  clz: 目標對象類型

  resultSet: 結果集

  public static List toBeans(ResultSet resultSet, Class clz) throws SQLException  轉換結果集為java對象集合.  clz: 要轉換的javaBean類

  resultSet: 結果集

  1.1 ResultSetUtil 源碼

  /** 結果集解析工具類

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public class ResultSetUtil {

  /** 轉換單行結果集為Map結構. key為列別名, value為列值

  * @param resultSet 查詢結果集

  * @return 結果集中為空時, 返回null

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public static LinkedHashMap toPropertyMap(ResultSet resultSet) throws SQLException {

  // 如果結果集為空,則返回null

  if (!resultSet.next()) return null;

  LinkedHashMap cloumnMap = new LinkedHashMap<>();

  // 獲取結果集元信息

  ResultSetMetaData metaData = resultSet.getMetaData();

  // 獲取每一列列名與值

  for (int i = 1; i <= metaData.getColumnCount(); i++) {

  // 獲取列別名為key

  String columnLabel = metaData.getColumnLabel(i);

  Object columnValue = resultSet.getObject(i);

  cloumnMap.put(columnLabel, columnValue);

  }

  return cloumnMap;

  }

  /** 轉換結果集為單行對象

  * @param clz 目標對象類型

  * @param resultSet 結果集

  * @since 1.0

  * @return null

  * @author zongf

  * @created 2019-07-18

  */

  public static T toBean(ResultSet resultSet, Class clz) {

  try {

  LinkedHashMap propertyMap = toPropertyMap(resultSet);

  return ReflectUtil.newInstance(clz, propertyMap, new DateTypeConverter());

  } catch (SQLException e) {

  throw new RuntimeException("sql 執行異常!", e);

  }

  }

  /** 轉換結果集為java對象集合.

  * @param clz 要轉換的javaBean類

  * @param resultSet 結果集

  * @return 結果集中沒有數據時, 返回null

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public static List toBeans(ResultSet resultSet, Class clz) throws SQLException {

  List list = new ArrayList<>();

  LinkedHashMap propertyMap = null;

  // 解析結果集

  while ((propertyMap = toPropertyMap(resultSet)) != null) {

  T t = (T) ReflectUtil.newInstance(clz, propertyMap, new DateTypeConverter());

  if(t != null) list.add(t);

  }

  return list.size() > 0 ? list : null;

  }

  }

  1.2 ReflectUtil 源碼

  這是筆者對使用到的反射技術封裝的一個簡單工具類.

  /** 反射工具類

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public class ReflectUtil {

  /**為對象屬性賦值

  * @param target 目標對象

  * @param property 屬性名

  * @param property 屬性名

  * @return value 屬性值

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public static void setPropertyValue(Object target, String property, Object value) {

  try {

  PropertyDescriptor descriptor = new PropertyDescriptor(property, target.getClass());

  Method writeMethod = descriptor.getWriteMethod();

  writeMethod.invoke(target, value);

  } catch (Exception e) {

  throw new RuntimeException("為對象屬性賦值異常!",e);

  }

  }

  /** 獲取對象屬性值

  * @param target 目標對象

  * @param property 屬性

  * @return Object 返回對象屬性值

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public static Object getPropertyValue(Object target, String property) {

  try {

  PropertyDescriptor descriptor = new PropertyDescriptor(property, target.getClass());

  Method readMethod = descriptor.getReadMethod();

  return readMethod.invoke(target);

  } catch (Exception e) {

  throw new RuntimeException("獲取對象屬性異常!",e);

  }

  }

  /** 反射創建對象

  * @param clz 目標對象的類型

  * @return propertiesMap 目標對象的屬性與值

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public static T newInstance(Class clz, HashMap propertiesMap, DateTypeConverter typeConverter){

  // 如果屬性為空, 則不進行創建, 返回null

  if (propertiesMap == null || propertiesMap.isEmpty()) {

  return null;

  }

  // 使用無參數構造方法創建對象

  T t = null;

  try {

  t = clz.newInstance();

  for (Map.Entry entry : propertiesMap.entrySet()) {

  // 獲取對象屬性與值

  String property = entry.getKey();

  Object value = entry.getValue();

  // 獲取屬性描述符

  PropertyDescriptor propertyDescriptor = new PropertyDescriptor(property, clz);

  // 獲取屬性類型

  Class propertyType = propertyDescriptor.getPropertyType();

  // 使用類型轉換器轉換參數類型

  value = typeConverter.convert(value, propertyType);

  // 調用set方法, 賦值

  Method writeMethod = propertyDescriptor.getWriteMethod();

  writeMethod.invoke(t, value);

  }

  } catch (Exception e) {

  throw new RuntimeException("反射創建對象失敗!", e);

  }

  return t;

  }

  } 無錫看婦科的醫院 http://www.ytsgfk120.com/

  1.3 DateTypeConverter 轉換器

  筆者僅僅編寫了一個日期類型的轉換器, 在企業開發中, 可能需要用到的轉換器會更多.

  /** 日期類型轉換器

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public class DateTypeConverter {

  /** 轉換對象的類型

  * @param value 值

  * @param javaType java類型

  * @return 轉換后的類型

  * @since 1.0

  * @author zongf

  * @created 2019-07-18

  */

  public Object convert(Object value, Class javaType) {

  Object obj = value;

  // 如果是java 日期

  if(javaType.equals(Date.class)) {

  java.sql.Date date = (java.sql.Date) value;

  obj = date.toInstant().getEpochSecond();

  // 如果是java8 日期

  } else if(javaType.equals(LocalDate.class)){

  obj = ((java.sql.Date) value).toLocalDate();

  } else {

  obj = value;

  }

  return obj;

  }

  }

  2. 單元測試

  2.1 創建javaBean

  測試時, 需要創建t_user表和javabean, 筆者這邊僅給出javabean的定義.

  public class UserPO {

  private Integer id;

  private String name;

  private String password;

  private LocalDate birthday;

  // 省略setter/getter/toString 方法

  }

  2.2 測試用例

  // 測試轉換單個對象為Map 結構

  @Test

  public void toPropertyMap() throws SQLException {

  String str = "select id uId, name , pwd, birthday from t_user where id = 1001";

  Connection connection = DbConnUtil.getConnection(true);

  Statement statement = connection.createStatement();

  ResultSet resultSet = statement.executeQuery(str);

  LinkedHashMap map = ResultSetUtil.toPropertyMap(resultSet);

  map.forEach((key, val) -> System.out.println(key + ":" + val));

  }

  // 測試轉換對象為單個bean

  @Test

  public void toBean() throws SQLException {

  String str = "select * from t_user where id = 1002";

  Connection connection = DbConnUtil.getConnection(true);

  Statement statement = connection.createStatement();

  ResultSet resultSet = statement.executeQuery(str);

  UserPO userPO = ResultSetUtil.toBean(resultSet, UserPO.class);

  System.out.println(userPO);

  }

  // 測試轉換對象為bean列表

  @Test

  public void toBeans() throws SQLException {

  String str = "select * from t_user ";

  Connection connection = DbConnUtil.getConnection(true);

  Statement statement = connection.createStatement();

  ResultSet resultSet = statement.executeQuery(str);

  List userPOList = ResultSetUtil.toBeans(resultSet, UserPO.class);

  userPOList.forEach(System.out::println);

  }


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巧家县| 盐城市| 两当县| 广昌县| 桐庐县| 长子县| 敦化市| 大庆市| 手机| 盈江县| 三亚市| 赣州市| 吉林省| 眉山市| 营口市| 韶山市| 横山县| 杭锦旗| 乐平市| 大关县| 武夷山市| 崇信县| 茶陵县| 新闻| 思南县| 定州市| 南和县| 建昌县| 社旗县| 肥西县| 梅河口市| 磐安县| 苍南县| 太仓市| 阳城县| 湾仔区| 廉江市| 光山县| 大厂| 东方市| 锡林郭勒盟|