4、JDBC、泛型和反射的小例子

关于JDBC的相关知识,可参考本人上文: 3、JDBC小疑惑

代码内容:利用JDBC返回数据库结果集,遍历结果集的数据后,利用反射将每个数据封装成一个实体对象,存入集合。

这段代码使用泛型可以让用户根据自身需要,反射不同的类对象,提升此代码的复用性,适用于想把数据库内容封装成实体对象的情况。前提是数据库属性名和实体对象中的属性名要一致,且实体对象类中各个属性有相应的setter方法。如果想直接在控制台打印出结果,还要在实体类中重写toString()方法。

数据库:mysql

public class ReflectTest {
    /**
     * @param t   类对象,利用类对象可以获取类的成员方法和成员变量(属性),以及创建类的实例
     * @param <T> 泛型,可以根据需要使用不同的类
     * @return 返回存放多个对象的集合
     * @throws Exception
     */
    public <T> ArrayList<T> findAll(Class<T> t) throws Exception {
        //连接数据库,返回结果集
        Class.forName("com.mysql.jdbc.Driver");
        //databaseName为实际的数据库名称,username和password也以用户实际设置为准
        String url = "jdbc:mysql://localhost:3306/databaseName";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        //
        String sql = "SELECT * FROM databaseName";
        PreparedStatement pst = conn.prepareStatement(sql);
        ResultSet rs = pst.executeQuery();

        ArrayList<T> list = new ArrayList<>();
        //获取类对象所有属性(getDeclaredFields():忽略访问权限,直接提取属性)
        Field[] fields = t.getDeclaredFields();

        while (rs.next()) {
            //调用类对象的newInstance()静态方法来实例化对象
            T obj = (T) t.newInstance();
            //根据每个属性,获取相应setXxx方法,将结果集数据存入对象
            for (Field field : fields) {
                String name = field.getName();
                //rs_obj:从结果集获取到的单个属性
                Object rs_obj = rs.getObject(name);
                //setXxx方法的第一个X要大写,这里要对字符串name进行第一个字母大写的处理
                char[] chars = name.toCharArray();
                chars[0] = (char) (chars[0] - 'a' + 'A');
                String methodName = "set" + String.valueOf(chars);
                //获取setXxx方法并执行,将单个属性封装到对象属性
                //getMethod()参数:第一个为方法名,后面为该方法所需参数类型的类对象,根据实际可以写多个参数类型
                Method method = t.getMethod(methodName,field.getType());
                method.invoke(obj, rs_obj);
            }
            list.add(obj);
        }

//        与上面方法对比:上者根据属性获取方法,下者根据方法获取属性,建议使用上者
//        Method[] methods = t.getMethods();
//        while (rs.next()) {
//            T obj = (T) t.newInstance();
//            for (Method method : methods) {
//                String name = method.getName();
//                if (name.contains("set")) {
//                    String field = name.substring(3, name.length()).toLowerCase();
//                    method.invoke(obj, rs.getObject(field));
//                }
//            }
//            list.add(obj);
//        }
        return list;
    }
    
    //这里是本人的测试,里面的User应为用户想要封装的实体对象类名称。
    //如果想在控制台成功打印对象,记得在实体对象类重写toString()方法,不然打印出来的会是一串串地址
    @Test
    public void mainTest() throws Exception {
        ArrayList<User> list = findAll(User.class);
        System.out.println(list);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值