MyBatis 是一款优秀的持久层框架。于原生的 JDBC 相比,MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的繁琐操作。在开发中是十分常用的框架之一。


1. MyBatis 的基本工作原理

MyBatis 应用的核心

每一个 MyBatis 应用的都是以一个 SqlSessionFactory 的实例为核心的。因为 SqlSessionFactory 实例是通过 SqlSessionFactoryBuilder 和 MyBatis 的配置文件构建出来,所以 SqlSessionFactory 包含了你对 MyBatis 配置的所有信息。

一个简单的构建 SqlSessionFactory 的例子:

// MyBatis 配置文件
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

MyBatis 配置文件

配置文件包含了对 MyBats 系统的核心设置,包括了获取数据库连接实例的数据源(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)等等相关配置。

MyBatis 还有一个特点就是 SQL 语句映射。MyBatis 可以将映射器 Mapper 中的方法与 XML 映射文件中的 SQL 语句构成映射关系。而这些 XML 映射文件也需要在 MyBatis 配置文件进行设置。

在构建 SqlSessionFactory 时,这些配置会作为 SqlSessionFactoryBuilder 参数传到 SqlSessionFactory 中去,SqlSessionFactory 就会根据这些配置文件构建出专门负责访问数据库的对象。

一个简单 MyBatis 配置文件例子:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- XML 映射文件 -->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>

MyBatis 访问数据库

因为 SqlSessionFactory 管理着 MyBatis 配置文件的所有信息,所以 SqlSessionFactory 会根据 MyBatis 的配置信息构建出 SqlSession 实例。SqlSession 实例同样会获取到 MyBatis 的配置文件信息,并且通过数据库相关信息,负责与数据库进行连接访问。

一个简单的 SqlSession 访问数据库的例子:

try (SqlSession session = sqlSessionFactory.openSession()) {
Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}

SqlSession 实例也可以通过 XML 映射文件信息获取相应的映射器实例,然后使用映射器实例访问数据库。

一个简单的映射器实例访问数据库的例子:

try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}

图解 MyBatis 的基本工作原理

根据上面讲解作出此图,以便理解:

mybatis core


2. MyBatis 组件

SqlSessionFactoryBuilder

这个类主要是负责创建 SqlSessionFactory 实例的,一旦 SqlSessionFactory 实例被创建,就再也不需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域就是方法作用域。

SqlSessionFactory

因为 SqlSessionFactory 管理着 MyBatis 所有的配置信息,所以它是 MyBatis 应用的核心组件,一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。因此 SqlSessionFactory 的最佳作用域是应用作用域,最简单的就是使用单例模式实现。

SqlSession

因为 SqlSession 实例不是线程安全的,所以 SqlSession 不能在应用中共享。每一个线程都需要一个独立的 SqlSession 实例。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

映射器实例

映射器是一些由你创建的、绑定 XML 映射文件中的 SQL 的接口,映射器实例是从 SqlSession 获取的。因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。尽管如此,映射器实例的最佳作用域是方法作用域。 也就是说,映射器实例应该在调用它们的方法中被请求,用过之后即可丢弃。


参考文献:

MyBatis 官方文档

评论