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 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 的灵魂,少了它就没那味儿了,