java jdbc ResultSet结果通过java反射赋值给java对象

Posted 草木物语

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

以上是关于java jdbc ResultSet结果通过java反射赋值给java对象的主要内容,如果未能解决你的问题,请参考以下文章

JDBC ResultSet 存储查询结果失败

jdbc

JDBC结果集

JDBC——ResultSet结果集对象

MYSQL 之 JDBC: 增删改查通过ResultSet执行查询操作

将JDBC ResultSet结果集转成List