JDBC模拟mybatis对象映射赋值

本文介绍如何使用Java反射机制模拟MyBatis的实体类映射过程,通过JDBC连接数据库,实现数据到实体类的自动填充,提供一个简单的示例代码和测试过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 模拟mybatis映射实体类


使用mybatis也有很长时间了,它的强大也是众所周知的,包括性能和灵活性等方面。说起它的强大,但是对象赋值也是一大亮点了,所以我做了一个模拟

在我的理解中,我觉得可以通过Java的反射机制,来模拟一次mybatis实体类的赋值,将实体类的set方法调用出来,今晚字段赋值,就可以实现,接下来演示一下代码。

1. 准备工作

1.1 Java:版本1.8
1.2 mysql包:5.1.44

其实可以不用跟着我的版本,根据自己的版本来

还需要一个JDBC工具类,因为是通过JDBC连接数据库,采用最原生的方式,实现模拟

JDBC工具类传送门:JDBC工具类

2. 模拟代码

    private static<T> T mappingObj(ResultSet resultSet, Class<T> clazz) {
        T obj = null;
        try {
            //实例化映射对象
            obj = clazz.newInstance();
            //获取映射对象的方法
            Method[] methods = clazz.getMethods();
            //获取结果集中元数据信息
            ResultSetMetaData meta = resultSet.getMetaData();
            // 按字段数目循环结果集中记录,进行对象映射
            for (int i = 1; i <= meta.getColumnCount(); i++) {
                // 构造当前列的set方法名称
                String columnName = meta.getColumnName(i);
                String methodName = "set" + columnName.replaceAll("[\\.|\\-|\\_]", "");
                // 循环查找同名方法,并通过反射调用该方法,设置属性
                for (Method method : methods) {
                    if (method.getName().equalsIgnoreCase(methodName)) {
                        method.invoke(obj, resultSet.getObject(i));
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

以上就是模拟赋值的核心代码,主要的思路就是靠传进来一个class,实例化获取对象,再利用JDBC的结果集对象,获取到当前连接数据库的表字段,通过Java反射机制,再两者合二为一

运用在实例当中

    /**
     * 获取数据库下的所有表字段名称
     *
     * @param dbConfig 数据库配置对象
     * @return List集合
     */
    public static List<String> getColumnNames(DbConfig dbConfig) {
        List<String> columnNames = new ArrayList<>();
        Connection connection = getConnection(dbConfig);
        PreparedStatement statement = null;
        String sql = "SELECT * FROM " + dbConfig.getTableName();
        try {
            statement = connection.prepareStatement(sql);
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                System.out.println(mappingObj(resultSet, Test.class));
            }
            //结果集元数据
            ResultSetMetaData metaData = statement.getMetaData();
            //表列数
            int size = metaData.getColumnCount();
            for (int i = 0; i < size; i++) {
                columnNames.add(metaData.getColumnName(i + 1));
            }
            logger.info("查询成功" + columnNames);
        } catch (SQLException e) {
            throw new SqlErrorException("获取数据库表字段失败:" + e.getMessage());
        } finally {
            closeConnection(connection, null, statement);
        }
        return columnNames;
    }
    public static void main(String[] args) {
        DbConfig config = new DbConfig();
        config.setUrl("127.0.0.1");
        config.setPort("3306");
        config.setDataBase("coon");
        config.setUser("root");
        config.setPassWord("root");
        config.setDriverClass("com.mysql.jdbc.Driver");
        config.setTableName("user");
        System.out.println(getColumnNames(config));
    }

运用在了一个简单获取表字段的方法中,在一个while循环中可以看到被调用到了,其中Test是我建立的一个测试类,里面的属性很简单,就是用户名和密码以及手机号码三个,看一下打印台的运行结果

Test{userName='测试用户', passWord='123456', userPhone='13000000000'}
Test{userName='测试用户', passWord='123456', userPhone='13000000000'}
Test{userName='测试用户', passWord='123456', userPhone='13000000000'}
Test{userName='测试用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
Test{userName='默认用户', passWord='123456', userPhone='13000000000'}
21:17:31.952 [main] INFO com.example.web.codegenerator.util.DataBaseUtil - 查询成功[user_id, user_name, password, user_level, user_phone, user_email, user_balance, user_integral, user_card]
21:17:31.952 [main] INFO com.example.web.codegenerator.util.DataBaseUtil - 数据库关闭连接
[user_id, user_name, password, user_level, user_phone, user_email, user_balance, user_integral, user_card]

大功告成,数据库中的几条数据都被打印了出来。这个只是一个思路模型,大致按照我的理解做了一次模拟,粗糙了一点,供大家参考一起学习,可以自行优化封装,说不定会派上用处呢,哈哈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值