Java实现自动映射原生JDBC查询出的数据库字段

这篇博客介绍了在不依赖框架如MyBatis或JPA的情况下,如何利用Java反射技术将数据库查询结果自动封装到对象中。通过示例展示了如何处理驼峰命名规则,并动态匹配字段,实现数据映射。这种方法在处理大量表和类映射时能提高代码维护性和效率。
摘要由CSDN通过智能技术生成

如今框架横行,很多人用的得心应手,可是很多人都没有了解过底层的东西,导致往后去学习别的框架的时候就不会那么顺利。就比如我们平时在写代码时,都会用MyBatis或者JPA,但是你了解过他们是怎么匹配字段的吗?如果突然不让使用框架,你还能那么轻松的写出来吗。
在原生JDBC的场景下,我们如何将查询的字段自动封装到对象中呢?就是通过Java的反射实现,这是一个很实用的技术。我们看一下下面的代码
这是一个数据库表对应的类,其中使用有驼峰命名

@Data
@TableName("t_admin")
public class Admin implements Serializable {
    @TableId("username")
    private String username;//用户名
    private String nickName;//用户昵称
    private String password;//用户密码
    private String email;//用户邮箱
    private String avatar;//用户头像
    private String qq;
    private String weChat;
    private String weChatQrCode;//微信收款码
    private String authorImage;//管理员主页图
    private String alipayQrCode;//管理员主页图
    private String weChatCode;//微信二维码
    private Integer type;//用户类型
}

对于这样一个类或者数据库,我们当然没有感觉它有多繁琐,可是当不同的类和数据表,或者表很多表或者类时,那将会怎么样呢?是不是觉得不好写,而且不容易维护,一旦程序出现变动,整个映射都需要重新更改。那么我们来看一下如何通过反射实现字段映射封装。

//可以封装起来,传入class或者对象
Admin admin;
        try {
        //这里可以通过反射创建
            admin = new Admin();
            String regex = "[A-Z]";//匹配驼峰规则
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(url, root, passwd);
            PreparedStatement ps = conn.prepareStatement("select * from t_admin where username = ? and password = ?");
            ps.setString(1, username);
            ps.setString(2, MyConfig.md5Code(password));
            ResultSet rs = ps.executeQuery();
            Class<? extends Admin> aClass = admin.getClass();
            Field[] fields = aClass.getDeclaredFields();//获得class中的属性
            StringBuilder sb = new StringBuilder();
            while (rs.next()) {
                //替换驼峰字符
                for (int i = 0; i < fields.length; i++) {
                    for (int j = 0; j < fields[i].getName().length(); j++) {
                        char ch = fields[i].getName().charAt(j);
                        if ((ch + "").matches(regex)) {
                            sb.append("_" + (ch + "").toLowerCase());
                        } else {
                            sb.append(ch);
                        }
                    }
                    //破坏私有属性
                    fields[i].setAccessible(true);
                    //这里可以根据字段进行判断,因为数据库字段是string和integer,所以只判断两个类
                    //这句代码的意思是判断两个类型是否是一个类型,可以根据自己的数据库进行编写(注意原始数据类型即可)
                    boolean b = String.class.isAssignableFrom(fields[i].getType());
                    if (b) {
                        fields[i].set(admin, rs.getString(sb.toString()));
                    } else {
                        fields[i].set(admin, rs.getInt(sb.toString()));
                    }
                    //重置sb(StringBuilder线程不安全,如果在多线程下请使用StringBuffer)
                    sb.setLength(0);
                }
            }
            rs.close();
            ps.close();
            conn.close();
            System.out.println(admin);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

注意需要导入mysql驱动
在这里插入图片描述
是不是觉得很简单

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值