使用反射封装方法,该方法可自动将任意表的查询结果封装到对应的实体类中,并将这些对象添加到集合中返回。

约束条件:1.实体类中的属性名必须和查询的列名一致;

                  2.实体类中的属性类型必须和所查询列的类型对应

方法名及参数为:

public <T> List executeQuery(Class<T> cla, String sql, Object... params){
     protected Connection conn = null;
     protected PreparedStatement ps = null;
     protected ResultSet rs = null;
}
//三个参数分别为所对应的实体类的class对象,SQL语句,可变参数。

第一步:连接数据库;

Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动,字符串内容为驱动所在的引用。
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javaweb-db",
 "root", "root");
// DriverManager.getConnection()中的三个参数分别为所调用的数据库的位置,
    数据库的账号,数据库的密码。 

第二步:创建预处理对象;

ps=conn.prepareStatement(sql);

第三步:设置?占位符的值。首先根据参数列表判断是否有?占位符;

if(params!=null&&params.length!=0){
    for(int i=0;i<params.length;i++){
        ps.setObject(i+1,params[i]);
    }
}

第四步:执行查询结果,返回结果集;

rs=ps.executeQuery();

第五步:创建一个List集合用于接收返回的对象;

List<T> list=new ArrayList<>();
//<T>表示返回值泛型,意思就是你给我什么我就返回什么

第五步:获得数据库的元文件;

ResultSetMetaData rsmd=rs.getMetaData();

第六步:通过遍历rs集合,进行反射操作;

while(rs.next()){
    //创建类对象
    T t=cla.getDeclaredConstructor().newInstance();
    //遍历rs集合
       for(int i=0;i<rsmd.getColumnCount();i++){
            //根据元文件获得对应的列名
            String columnName=rsmd.getColumnName(i+1);
            //根据列的编号获得每列数据
            Object val=rs.getObject(i+1);
            //获得属性值
            Field fieldName=cla.getDeclaredField(columnName);
            //拼接set方法名
            String    methodName="set"+columnName.substring(0,1).toUpperCase()
                                  +columnName.substring(1);
            //获取set方法
            Method method=cla.getDeclaredMethod(methodName,fieldName.getType());
            //调用set方法
            method.invoke(t, ConvertUtils.convert(val,fieldName.getType()));
        }
    list.add(t);
    }
return list;

总结:需要特别注意的是:并不是根据数据库的表的结构进行输出,不是说表中有多少列就输出多少列。而是通过灵活的通过sql语句,来得到输出的内容,进而确定需要操作哪些列。这里就用到了元文件,元文件中的内容主要就是表的结构(即就是我们在数据库中点击“设计表”出现的内容)。rs结果集通过ResultSetMetaData rsmd=rs.getMetaData();得到rsmd,即输出的元文件。进而通过rsmd.getColumnCount()得到一共输出了哪些列,通过rsmd.getColumnName(参数:列号)获得列的名字。然后进行反射操作。

完整代码:

 public <T> List executeQuery(Class<T> cla, String sql, Object... params){
     //连接数据库
    Class.forName("com.mysql.cj.jdbc.Driver");
    return conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javaweb-db?,                                 
                   "root", "root");
    //创建预处理对象
     ps=conn.prepareStatement(sql);
     //设置?占位符的值,根据parmas参数判断,sql语句是否含有?占位符
     if(params!=null&&params.length!=0){
        for(int i=0;i<params.length;i++){
             ps.setObject(i+1,params[i]);
             }
        }
      //创建一个List对象
      List<T> list=new ArrayList<>();
       //执行查询结果,返回结果集
       rs=ps.executeQuery();
       //获得数据库的元文件
       ResultSetMetaData rsmd=rs.getMetaData();
       while(rs.next()){
       //创建类对象
                T t=cla.getDeclaredConstructor().newInstance();
                //遍历rs集合
                for(int i=0;i<rsmd.getColumnCount();i++){
                    //根据元文件获得对应的列名
                    String columnName=rsmd.getColumnName(i+1);
                    //根据列的编号获得每列数据
                    Object val=rs.getObject(i+1);
                    //获得属性值
                    Field fieldName=cla.getDeclaredField(columnName);
                    //拼接set方法名
                    String methodName="set"+columnName.substring(0,1).toUpperCase()
                                       +columnName.substring(1);
                    //获取set方法
                    Method method=cla.getDeclaredMethod(methodName,fieldName.getType());
                    //调用set方法
                    method.invoke(t, ConvertUtils.convert(val,fieldName.getType()));
                }
                list.add(t);

            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            this.closeAll();
        }
        return  null;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值