浅析MyBatis(一):由一个快速案例剖析MyBatis的整体架构与运行流程

时间:2024-01-28 18:37:09

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