核心模块概览

MyBatis 源码包含以下模块:

  annotations  --- 注解相关
binding      --- 代理类生成相关
builder      --- 构造器模块
cache        --- 缓存相关,用于实现一级、二级缓存
cursor       --- 数据游标
datasource   --- 数据源模块
exceptions   --- 异常模块
executor     --- 执行器模块
io           --- 配置文件 I/O
jdbc         --- 与 JDBC 交互的中间层
lang         --- JDK 版本注解
logging      --- 日志模块
mapping      --- 映射模块,负责保存每条 SQL 需要的各种信息
parsing      --- 解析器模块
plugin       --- 扩展插件模块
reflection   --- 反射工具模块
scripting    --- 动态 SQL 生成模块
session      --- 会话模块,核心
transaction  --- 简易事务管理器
type         --- 类型转换模块
util         --- 工具类
  

其中主要模块的详细功能如下。

session 模块

Session(会话)模块是 MyBatis 与用户交互的核心,内部包含我们最为熟悉的 SqlSessionSqlSessionFactory 接口。最核心的接口是 SqlSession,通过它我们可以实现许多功能,例如获取 Mapper 代理、执行 SQL 语句以及控制事务等。

mapping 模块

Mapping 模块是 MyBatis 的核心,每条 SQL 语句都会被封装为一个 MappedStatement 对象。MappedStatement 包含了执行 SQL 所需的各种信息,主要包括以下几个方面:

  1. SQL 语句定义:存储并管理映射的 SQL 语句,可以是静态的 SQL,也可以是动态 SQL。
  2. 参数映射:定义输入参数的类型及其在 SQL 语句中的位置。
  3. 结果映射:定义 SQL 查询结果与 Java 对象之间的映射关系。
  4. 缓存配置:支持对查询结果的缓存,提供一级和二级缓存配置。
  5. 执行配置:包含执行 SQL 语句时的各种配置,如超时时间、执行模式(如查询、插入、更新、删除)等。

io 模块

该模块通过 I/O 流将配置文件加载到内存,比较简单这里略过了。

type 模块

Type 模块用于完成 JDBC 类型与 Java 类型之间的相互转换

MyBatis 类型转换
  • 在 SQL 模板绑定用户传入实参的场景中,类型转换模块会将 Java 类型数据转换成 JDBC 类型数据;
  • 在将结果集映射成结果对象的时候,类型转换模块会将 JDBC 类型数据转换成 Java 类型数据。

此外,该模块还实现了 typeAliases 别名机制。

logging 模块

MyBatis 通过 logging 模块来集成 Java 生态中的第三方日志框架,该模块目前可以集成 Log4j、Log4j2、slf4j 等优秀的日志框架。

reflection 模块

MyBatis 的 reflection 模块对 Java 反射机制进行了封装,为上层应用提供了更加灵活、方便的 API 接口。同时,它缓存了与 Java 反射相关的元数据,提升了反射代码执行的效率,优化了反射操作的性能。

binding 模块

Binding 模块用于生成 mapper 接口的代理实现。我们可以通过 SqlSession 获取 Mapper 接口的代理,并通过该代理执行关联的 mapper.xml 文件中的数据库操作。

datasource 模块

MyBatis 的 datasource 模块负责管理和提供数据库连接,提供了数据源的配置、管理以及与数据库的交互功能。

cache 模块

数据库是生产中最核心的组件,很多业务数据都会落地到数据库,所以数据库性能的优劣直接影响了上层业务系统的优劣。我们很多线上业务都是读多写少的场景,在数据库遇到瓶颈时,缓存是最有效、最常用的手段之一,正确使用缓存可以将一部分数据库请求拦截在缓存这一层,这就能够减少一部分数据库的压力,提高系统性能。

MyBatis 的一级缓存和二级缓存实现都依赖该模块。

parsing 模块

Parsing 模块用于解析 MyBatis 的 核心配置文件映射配置文件

transaction 模块

MyBatis 对数据库中的事务进行了一层简单的抽象,提供了简单易用的事务接口和实现。

不过现代 Java 项目往往会集成 Spring,并由 Spring 框架管理事务,因此一般我们会将 MyBatis 事务接口的实现委托给 Spring。

scripting 模块

动态 SQL 功能是 MyBatis 的一大亮点,只需使用 MyBatis 提供的标签,即可根据实际的运行条件动态生成要执行的 SQL 语句。MyBatis 提供了丰富的动态 SQL 标签,包括 <where> 标签、<if> 标签、<foreach> 标签、<set> 标签等。

MyBatis 通过 scripting 模块动态生成 SQL。它会根据运行时用户传入的实参,解析动态 SQL 中的标签,并形成 SQL 模板,然后处理 SQL 模板中的占位符,用运行时的实参填充占位符,得到数据库真正可执行的 SQL 语句。

Executor 模块

Executor 模块是 MyBatis 的另一个核心,涉及非常多的组件,主要有 ExecutorStatementHandlerParameterHandlerResultSetHandler 等:

  • Executor 负责 SQL 动态语句的生成,同时会通过缓存模块管理一级缓存和二级缓存。
  • SQL 语句的真正执行将会由 StatementHandler 实现。StatementHandler 会先依赖 ParameterHandler 进行 SQL 模板的实参绑定。
  • 然后通过 JDBC 中的 java.sql.Statement 将 SQL 语句以及绑定好的实参传到数据库执行。
  • 最后,从数据库中拿到 ResultSet,并由 ResultSetHandlerResultSet 映射成 Java 对象返回给调用方。

plugin 模块

很多成熟的开源框架,都会以各种方式提供扩展能力。当框架原生能力不能满足某些场景的时候,就可以针对这些场景实现一些插件来满足需求,这样的框架才能有足够的生命力。

核心组件概览

了解了 MyBatis 的核心模块,下面我们再来了解一下执行过程中涉及的核心组件:

  +---------------------------------------+   +-----------------+
|              SqlSession               |   |  Configuration  +-------+
+---+-----------------------------------+   +-----------------+       |
    |                               ^                                 |
    v                               |                                 |
+-----------------------------------+---+                             |
|               Executor                |                             |
+---+-----------------------------------+                             |
    |                               ^       +----------+              |
    v                               |     +-| BoundSql |              |
+-----------------------------------+---+ | +----------+              |
|           StatementHandler            +-|                           |
+-++------------------------------------+ | +-----------------------+ |
  ||                                 ^    +-|    MappedStatement    +-+
  ||                                 |      |-----------------------|
  |v                                 |      | SqlSource & ResultMap |
+-|----------------+ +---------------+--+   +-----------------------+
| ParameterHandler | | ResultSetHandler |
+-|------------+---+ +--^-----^---------+
  |            |        |     |
  |        +---v--------+---+ |
  |        | TypeHandler<T> | |
  |        +-+--------^-----+ |
  |          |        |       |
+-|----------|--------|-------|---------+
| |          |    +---+-------+     JDBC|
| |          |    | ResultSet |         |
| |          |    +--------^--+         |
| |          |             |            |
| v----------v-------------+------+     |
| |           Statement           |     |
| | +------------------+ +-------+|     |
| | | PrepareStatement | |  ...  ||     |
| | +------------------+ +-------+|     |
| +-------------------------------+     |
+---------------------------------------+
  
  • MyBatis 通过会话机制执行 SQL,顶层接口为 SqlSession
  • Executor 执行器是 MyBatis 的核心,它负责动态 SQL 的生成,和查询缓存的维护;
  • StatementHandler 负责与 JDBC 交互,包括对 Statement 设置参数,以及将 JDBC 返回的 ResultSet 封装为 List。