MyBatis 是轻量级的 Java 持久层中间件,完全基于 JDBC 实现持久化的数据访问,支持以 xml 和注解的形式进行配置,能灵活、简单地进行 SQL 映射,也提供了比 JDBC 更丰富的结果集,应用程序可以从中选择对自己的数据更友好的结果集。本文将从一个简单的快速案例出发,为读者剖析 MyBatis 的整体架构与运行流程。本次分析中涉及到的代码和数据库表可以从 GitHub 上下载:mybatis-demo 。
1.一个简单的 MyBatis 快速案例
MyBatis官网 给出了一个 MyBatis 快速入门案例,简单概括下来就是如下步骤:
- 创建 Maven 项目并在 pom.xml 文件中引入 MyBatis 的依赖;
- 准备数据库连接配置文件(database.properties)及 MyBatis 配置文件(mybatis-config.xml);
- 准备数据库表单对应的实体类(Entity)以及持久层接口(Mapper/Dao);
- 编写持久层接口的映射文件(Mapper/Dao.xml);
- 编写测试类。
创建学生表用于测试:
CREATE TABLE `student` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '学生ID',
`name` varchar(20) DEFAULT NULL COMMENT '姓名',
`sex` varchar(20) DEFAULT NULL COMMENT '性别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
该表单对应的实体类以及包括增删改查方法的持久层接口可在 entity 包和 mapper 包查看,数据库连接和 MyBatis 的配置文件以及持久层接口的映射文件可以在 resource 包下查看。
测试类如下:
public class StudentTest {
private InputStream in;
private SqlSession sqlSession;
@Before
public void init() throws IOException {
// 读取MyBatis的配置文件
in = Resources.getResourceAsStream("mybatis-config.xml");
// 创建SqlSessionFactory的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 使用builder创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
// 使用factory创建sqlSession对象并设置自动提交事务
sqlSession = factory.openSession(true);
}
@Test
public void test() {
// 使用sqlSession创建StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 使用代理对象执行相关方法
System.out.println(studentMapper.getStudentById(2));
studentMapper.updateStudentName("托尼·李四", 2);
System.out.println(studentMapper.getStudentById(2));
System.out.println(studentMapper.findAll());
}
@After
public void close() throws IOException {
// 关闭资源
sqlSession.close();
in.close();
}
}
测试类运行结果如下:
可以看到测试类成功执行了相应方法,这样就完成了 MyBatis 的快速案例实现。要注意的是,在上面的案例中我们采用的是为持久层接口编写相应 xml 映射文件的方法,其部分配置如下所示:
<select id="getStudentById" parameterType="int" resultType="com.chiaki.entity.Student">
SELECT id,name,sex FROM student WHERE id = #{id}
</select>
此外,在 MyBatis 中还提供了基于 Java 注解的方式,即在持久层接口的方法前使用对应的注解,如下所示:
@Select("SELECT id,name,sex FROM student WHERE id = #{id}")
Student getStudentById(int id);
两种方法各有优劣。基于注解的方法减少了配置文件,使代码更加简洁,但是在面对复杂 SQL 时候会显得力不从心;基于配置文件的方法虽然需要编写配置文件,但其处理复杂 SQL 语句的能力更强,实现了 Java 代码与 SQL 语句的分离,更容易维护。在笔者看来, Mapper.xml 配置文件就像是 MyBatis 的灵魂,少了它就没那味儿了,