zoukankan      html  css  js  c++  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

  • 相关阅读:
    万能分页方法!机会难得,在此送给大家
    Java长存!12个Java长久占居主要地位的原因
    angularjs1.x radio组checkbox组
    js动态显示vlc视频直播
    Lodop 分页详解,可详细了呢
    lodop 实现分页打印账单 最后一页右下角加入确认签字
    lodop分页,页眉页脚,foreach分页代码
    ajax最简单验证
    Httpcilent获取带验证码的网站内容
    设计模式(转载)
  • 原文地址:https://www.cnblogs.com/ooo0/p/10225311.html
Copyright © 2011-2022 走看看