MyBatis3源码解析(1)探索准备

本文通过对比原生JDBC与MyBatis操作数据库的方法,展示了MyBatis如何简化数据库连接、查询设置及结果映射的过程。通过具体示例说明了MyBatis能显著减少代码量并提高代码可读性。

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

简介

本篇文章将使用原生的JDBC方式操作数据库,然后在使用Mybatis提供的方式操作数据库,通过对比两部分的操作,大致得到Mybatis所做的主要工作,为接下来的源码解析做准备

示例代码

完整的工程已放到GitHub上:https://github.com/lw1243925457/MybatisDemo/tree/master/example

原生的JDBC操作数据库

我们简单是写一个连接数据库、创建表、插入、查询、关闭的示例,如下所示:

public class JdbcTest {

    @Test
    public void test() {
        Connection conn = null;
        Statement stmt = null;
        try {
            // STEP 1: 连接数据库
            // JDBC driver name and database URL
            String JDBC_DRIVER = "org.h2.Driver";
            Class.forName(JDBC_DRIVER);

            System.out.println("Connecting to database...");
            String DB_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";
            //  Database credentials
            String USER = "sa";
            String PASS = "";
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            //STEP 2: 设置参数,查询
            System.out.println("Creating table in given database...");
            stmt = conn.createStatement();
            String sql =  "CREATE TABLE   REGISTRATION " +
                    "(id INTEGER not NULL, " +
                    " first VARCHAR(255), " +
                    " last VARCHAR(255), " +
                    " age INTEGER, " +
                    " PRIMARY KEY ( id ))";
            stmt.executeUpdate(sql);
            System.out.println("Created table in given database...");

            //STEP 4: 处理查询结果
            String insertSql = "insert into REGISTRATION (id, first, last, age) values (?, ?, ?, ?)";
            PreparedStatement insertPreparedStatement = conn.prepareStatement(insertSql);
            insertPreparedStatement.setInt(1, 1);
            insertPreparedStatement.setString(2, "1");
            insertPreparedStatement.setString(3, "1");
            insertPreparedStatement.setInt(4, 1);
            insertPreparedStatement.executeUpdate();

            String querySql = "select * from REGISTRATION";
            ResultSet resultSet = stmt.executeQuery(querySql);
            ResultSetMetaData metaData = resultSet.getMetaData();
            while (resultSet.next()) {
                Registration registration = new Registration();
                registration.setId(resultSet.getInt(metaData.getColumnName(1)));
                registration.setFirst(resultSet.getString(metaData.getColumnName(2)));
                registration.setLast(resultSet.getString(metaData.getColumnName(3)));
                registration.setAge(resultSet.getInt(metaData.getColumnName(4)));
                System.out.println(registration);
            }

            // STEP 4: 关闭连接
            stmt.close();
            conn.close();
        } catch(Exception se) {
	    ......
        } //end try
        System.out.println("Goodbye!");
    }

    @Data
    static class Registration {
        private int id;
        private String first;
        private String last;
        private int age;
    }
}

如上代码所示,核心的步骤如下:

  • 1.连接数据库
  • 2.查询,设置参数
  • 3.得到查询结果,转成我们想要的对象
  • 4.关闭连接

1和4看着还好,但2和3,如果要硬是这样写的话,那代码可以感受很大的重复性,写很多的这样的代码就是一种折磨吧,哈哈

MyBatis操作数据库示例

下面我们来看看Mybatis3是如果操作的,示例代码如下:

为了简单,没有采用配置文件等方式,我们直接使用java代码的方式进行简单的配置

public class MybatisTest {

    @Test
    public void test() {
	// 得到数据库链接
        try(SqlSession session = buildSqlSessionFactory().openSession()) {
            PersonMapper personMapper = session.getMapper(PersonMapper.class);
	    // 创建表
            personMapper.createTable();
	    // 插入数据
            personMapper.save(Person.builder().id(1L).name("1").build());
	    // 查询数据
            Person person = personMapper.getPersonById(1);
            System.out.println(person);
        }
    }

    // 构建数据库的连接信息和配置Mapper
    public static SqlSessionFactory buildSqlSessionFactory() {
        String JDBC_DRIVER = "org.h2.Driver";
        String DB_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";
        String USER = "sa";
        String PASS = "";
        DataSource dataSource = new PooledDataSource(JDBC_DRIVER, DB_URL, USER, PASS);
        Environment environment = new Environment("Development", new JdbcTransactionFactory(), dataSource);
        Configuration configuration = new Configuration(environment);
        configuration.addMapper(PersonMapper.class);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        return builder.build(configuration);
    }
}

public interface PersonMapper {

    @Insert("create table person(id int not null, name varchar(255))")
    Integer createTable();

    @Insert("Insert into person(id, name) values (#{id}, #{name})")
    Integer save(Person person);

    @Select("Select id, name from Person where id=#{id}")
    @Results(value = {
            @Result(property = "id", column = "id"),
            @Result(property="name", column = "name"),
    })
    Person getPersonById(Integer personId);
}

如上,我们可以看到代码量相比直接操作数据库少了很多,而且可读性也比直接操作数据库好

最大的简化点在:

  1. 自动构建设置了查询相关的参数,语义清晰,如示例中查询表明根据Id查询

  2. 自动映射转换结果成我们定义的业务对象,大大简化了操作

总结

从上面的示例代码中,我们大致感受到了MyBatis所做的主要工作,所以我们解析的源码分析工作会从下面的方面展开:

  • 1.Mybatis的数据库连接
  • 2.Mybatis的查询
  • 3.Mybatis的结果映射
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值