zoukankan      html  css  js  c++  java
  • JAVA JDBC 利用反射对一个表动态查询

    所谓动态查询,就是查询的时候,不确定查询的列数,也不确定查询的哪几个列.

    通过反射可以完成这个操作:

    我们在构造sql语句的时候,动态传入条件.在结果集中,通过获取结果集的列名,来进行赋值.

     * 针对于表的字段名与类的属性名不相同的情况:
         * 1. 必须声明sql时,使用类的属性名来命名字段的别名
         * 2. 使用ResultSetMetaData时,需要使用getColumnLabel()来替换getColumnName(),
         *    获取列的别名。
         *  说明:如果sql中没有给字段其别名,getColumnLabel()获取的就是列名

    我们这样构造查询函数:

    public Customer queryForCustomers(String sql,Object...args){}

    然后这样还原sql语句

    ps = conn.prepareStatement(sql);
    for(int i = 0;i < args.length;i++){
        ps.setObject(i + 1, args[i]);
    }

    然后这样利用反射构造javabean

    //获取结果集的元数据 :ResultSetMetaData
    ResultSetMetaData rsmd = rs.getMetaData();
    //通过ResultSetMetaData获取结果集中的列数
    int columnCount = rsmd.getColumnCount();
    
    if(rs.next()) {
        Customer cust = new Customer();
        //处理结果集一行数据中的每一个列
        for (int i = 0; i < columnCount; i++) {
            //获取列值
            Object columValue = rs.getObject(i + 1);
            //获取每个列的列名
            String columnLabel = rsmd.getColumnLabel(i + 1);
    
            //给cust对象指定的columnName属性,赋值为columValue:通过反射
            Field field = Customer.class.getDeclaredField(columnLabel);
            field.setAccessible(true);
            field.set(cust, columValue);
        }
    }

    完整代码

    public Customer queryForCustomers(String sql,Object...args){
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JDBCUtils.getConnection();
                
                ps = conn.prepareStatement(sql);
                for(int i = 0;i < args.length;i++){
                    ps.setObject(i + 1, args[i]);
                }
                
                rs = ps.executeQuery();
                //获取结果集的元数据 :ResultSetMetaData
                ResultSetMetaData rsmd = rs.getMetaData();
                //通过ResultSetMetaData获取结果集中的列数
                int columnCount = rsmd.getColumnCount();
                
                if(rs.next()){
                    Customer cust = new Customer();
                    //处理结果集一行数据中的每一个列
                    for(int i = 0;i <columnCount;i++){
                        //获取列值
                        Object columValue = rs.getObject(i + 1);
                        
                        //获取每个列的列名
    //                    String columnName = rsmd.getColumnName(i + 1);
                        String columnLabel = rsmd.getColumnLabel(i + 1);
                        
                        //给cust对象指定的columnName属性,赋值为columValue:通过反射
                        Field field = Customer.class.getDeclaredField(columnLabel);
                        field.setAccessible(true);
                        field.set(cust, columValue);
                    }
                    return cust;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                JDBCUtils.closeResource(conn, ps, rs);
                
            }
            
            return null;
            
            
        }
    View Code

     这个代码是针对一张表的查询,我们可以利用泛型,编写查询任意表的通用操作

    public <T> T getInstance(Class<T> cl,String sql,Object ...args)throws Exception{
            InputStream is = connectTest.class.getClassLoader().getResourceAsStream("jdbcInfo.properties");
            Properties pro = new Properties();
            pro.load(is);
    
            String user = pro.getProperty("user");
            String password = pro.getProperty("password");
            String url = pro.getProperty("url");
            String driverClass = pro.getProperty("driverClass");
            //利用反射
            Connection connection = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            T t = null;
            try {
                Class.forName(driverClass);
                connection = DriverManager.getConnection(url,user,password);
                System.out.println(connection);
    
                ps = connection.prepareStatement(sql);
                for(int i=0;i<args.length;i++)
                    ps.setObject(i+1,args[i]);
                rs = ps.executeQuery();
                //获取结果集的元数据
                ResultSetMetaData md = rs.getMetaData();
                //获取结果集元数据中的列数
                int columnCount = md.getColumnCount();
    
                if(rs.next()){
                    //利用反射动态加载数据
                    t = cl.newInstance();
                    for(int i=0;i<columnCount;i++){
                        Object colDate = rs.getObject(i+1);
                        String colName = md.getColumnLabel(i+1);
                        Field var = cl.getDeclaredField(colName);
                        var.setAccessible(true);
                        var.set(t,colDate);
    
    
                    }
                    System.out.println(t);
                    return t;
                }
    
    
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
    
            } finally {
                if(ps!=null)
                    try {
                        ps.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                if(connection!=null)
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                if(rs!=null){
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                return t;
            }
    利用泛型查询任意表
  • 相关阅读:
    C/C++打印堆栈信息
    adb shell input keyevent值所对应的字符
    Nautilus-Share-Message: Called "net usershare info" but it failed: Failed to
    ubuntu 安装lua错误
    ubuntu 16.04 安装jdk9错误
    国家统计信息查询网址
    Spring ApplicationListener配合-D实现参数初始化
    Feign Form表单POST提交
    window下绝对路径
    SpringBoot中使用配置文件
  • 原文地址:https://www.cnblogs.com/superxuezhazha/p/12396683.html
Copyright © 2011-2022 走看看