1. 程式人生 > >java jdbc ResultSet結果通過java反射賦值給java物件

java jdbc ResultSet結果通過java反射賦值給java物件

在不整合框架的情況下,使用jdbc從資料庫讀取資料時都得一個個的get和set,不僅累程式碼還顯得不簡潔,所以利用java的反射機制寫了一個工具類,這樣用jdbc從資料庫拿資料的時候就不用那麼麻煩了。

因為很多情況下資料不止一條,所以返回的是物件類的一個集合。

需要注意的地方:在這裡,資料庫欄位命名格式為:user_name 下劃線格式,而java型別的命名格式為駝峰命名格式。

具體程式碼如下:

 

package com.xc.sap.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import cnblogs.com.ooo0.oracle.OperateOracle; public class Test { public static void main(String[] args) { try { // oracle資料庫連線 OperateOracle oo = new OperateOracle();//https://www.cnblogs.com/ooo0/p/10225374.html
Connection connection
= oo.getConnection(); String mainSql = "select * from users"; PreparedStatement pstm = connection.prepareStatement(mainSql); ResultSet rs = pstm.executeQuery(); ArrayList<Users> putResult = ResultSetPropertiesSimplifyHelps.putResult(rs, Users.class
); for (int i = 0; i < putResult.size(); i++) { System.out.println(putResult.get(i).toString()); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

 

package com.xc.sap.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;

/**
 * java jdbc ResultSet結果通過java反射賦值給java物件
 * 
 * @author xc
 */
public class ResultSetPropertiesSimplifyHelps {

    /**
     * 把ResultSet的結果放到java物件中
     * 
     * @param <T>
     * @param rs
     *            ResultSet
     * @param obj
     *            java類的class
     * @return
     */
    public static <T> ArrayList<T> putResult(ResultSet rs, Class<T> obj) {
        try {
            ArrayList<T> arrayList = new ArrayList<T>();
            ResultSetMetaData metaData = rs.getMetaData();
            /**
             * 獲取總列數
             */
            int count = metaData.getColumnCount();
            while (rs.next()) {
                /**
                 * 建立物件例項
                 */
                T newInstance = obj.newInstance();
                for (int i = 1; i <= count; i++) {
                    /**
                     * 給物件的某個屬性賦值
                     */
                    String name = metaData.getColumnName(i).toLowerCase();
                    name = toJavaField(name);// 改變列名格式成java命名格式
                    String substring = name.substring(0, 1);// 首字母大寫
                    String replace = name.replaceFirst(substring, substring.toUpperCase());
                    Class<?> type = null;
                    try {
                        type = obj.getDeclaredField(name).getType();// 獲取欄位型別
                    } catch (NoSuchFieldException e) { // Class物件未定義該欄位時,跳過
                        continue;
                    }

                    Method method = obj.getMethod("set" + replace, type);
                    /**
                     * 判斷讀取資料的型別
                     */
                    if (type.isAssignableFrom(String.class)) {
                        method.invoke(newInstance, rs.getString(i));
                    } else if (type.isAssignableFrom(byte.class) || type.isAssignableFrom(Byte.class)) {
                        method.invoke(newInstance, rs.getByte(i));// byte 資料型別是8位、有符號的,以二進位制補碼錶示的整數
                    } else if (type.isAssignableFrom(short.class) || type.isAssignableFrom(Short.class)) {
                        method.invoke(newInstance, rs.getShort(i));// short 資料型別是 16 位、有符號的以二進位制補碼錶示的整數
                    } else if (type.isAssignableFrom(int.class) || type.isAssignableFrom(Integer.class)) {
                        method.invoke(newInstance, rs.getInt(i));// int 資料型別是32位、有符號的以二進位制補碼錶示的整數
                    } else if (type.isAssignableFrom(long.class) || type.isAssignableFrom(Long.class)) {
                        method.invoke(newInstance, rs.getLong(i));// long 資料型別是 64 位、有符號的以二進位制補碼錶示的整數
                    } else if (type.isAssignableFrom(float.class) || type.isAssignableFrom(Float.class)) {
                        method.invoke(newInstance, rs.getFloat(i));// float 資料型別是單精度、32位、符合IEEE 754標準的浮點數
                    } else if (type.isAssignableFrom(double.class) || type.isAssignableFrom(Double.class)) {
                        method.invoke(newInstance, rs.getDouble(i));// double 資料型別是雙精度、64 位、符合IEEE 754標準的浮點數
                    } else if (type.isAssignableFrom(BigDecimal.class)) {
                        method.invoke(newInstance, rs.getBigDecimal(i));
                    } else if (type.isAssignableFrom(boolean.class) || type.isAssignableFrom(Boolean.class)) {
                        method.invoke(newInstance, rs.getBoolean(i));// boolean資料型別表示一位的資訊
                    } else if (type.isAssignableFrom(Date.class)) {
                        method.invoke(newInstance, rs.getDate(i));
                    }
                }
                arrayList.add(newInstance);
            }
            return arrayList;

        } catch (InstantiationException | IllegalAccessException | SQLException | SecurityException | NoSuchMethodException | IllegalArgumentException
                | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 資料庫命名格式轉java命名格式
     * 
     * @param str
     *            資料庫欄位名
     * @return java欄位名
     */
    public static String toJavaField(String str) {

        String[] split = str.split("_");
        StringBuilder builder = new StringBuilder();
        builder.append(split[0]);// 拼接第一個字元

        // 如果陣列不止一個單詞
        if (split.length > 1) {
            for (int i = 1; i < split.length; i++) {
                // 去掉下劃線,首字母變為大寫
                String string = split[i];
                String substring = string.substring(0, 1);
                split[i] = string.replaceFirst(substring, substring.toUpperCase());
                builder.append(split[i]);
            }
        }

        return builder.toString();
    }

}

 

參考文章:

https://blog.csdn.net/a975261294/article/details/70049963

優化內容:

1.NoSuchFieldException異常處理,Class物件未定義該欄位時,跳過

2.完善了大部分的基本資料型別的取值 http://www.runoob.com/java/java-basic-datatypes.html