#MyBatis 架构原理#

50 阅读4分钟

我们把 MyBatis 的功能架构分为三层:

  1. API 接口层
  2. 数据处理层
  3. 基础支撑层

API 接口层

首先我们先来说接口层, 接口层主要是提供给外部使⽤的 API,开发⼈员通过这些本地 API 来操纵数据库 。我们知道 MyBatis 提供了两种接口的调用方式,一种是传统方式(基于 statementId),另一种基于 Mapper 代理方式(基于 Mapper 接口的)。

传统方式的话,我们在调用接口层调用方法时,可以使用 sqlSession.selectList、或者 selectOne 或者 insert 等方法。这些方法是 MyBatis 提供对外使用的 API。我们可以在这些方法被调用的时候,传递 statementId,根据这个 statementId 来定位这条 SQL 语句,然后执行。

而使用 Mapper 代理方式的话,sqlSession 调用方法时就会掉 getMapper(...) 这个方法,拿到某个接口的代理对象,再由代理对象进行方法的调用。

不管我们使用基于 statementId 的传统方式,还是使用基于 Mapper 接口的代理方式,都是使用了 MyBatis 对外提供的 API。

数据处理层

开发人员通过调用这些 API 来操作数据库。当接口层接收到请求就会调用数据处理层来完成具体的数据处理。比如:我们执行了 sqlSession.selectList,当我们在执行这个语句的时候,其底层会调用数据处理层,数据处理层会去真正的完成 sql 的执行,所以说 MyBatis 其本身就是对 JDBC 的一个封装,其底层的还是 JDBC。为了能执行成功,需要进行、参数的设置、SQL 的预编译,SQL 的执行以及结果集封装和映射。

在 MyBatis 中:

  • 参数的映射:ParameterHandler
  • SQL 的解析: SqlSource
  • SQL 的执行: Executor
  • 结果集的处理和映射: ResultSetHandler

所以数据处理层的作用,负责具体的 SQL 查找、SQL 解析、SQL 执行和执行得到的结果映射处理等,主要目的是根据调用的请求完成一次数据库操作。

基础支撑层

负责最基础的功能支撑,包括了:事务管理、连接池管理、缓存机制等。

我们执行 SQL 是一定会与数据库进行交互的,所以,对于事务、连接池、缓存这些都会用到的,那么我们可以把这些最基础的、公用的抽取成组件,为上层的数据处理提供最基础的支撑。

下图是架构原理图:

MyBatis 中的主要构件及其相互关系

在上一张中我们介绍了 MyBatis 的架构设计,接下来我们介绍下 MyBatis 中的主要组件,以及他们之间的相互关系。

这里我列出了九个比较重要的构件:

构件描述
SqlSession做为 MyBatis 工作的主要顶层 API,表示和数据库连接的会话,完成对数据库的增删改查
ExecutorMyBatis 的执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成和查询缓存的维护
StatementHandler封装了 JDBC Statement 操作,负责对 JDBC Statement 的操作。如:设置参数、将 Statement 结果集转换为 List 集合。
ParameterHandler负责对用户传递的参数转换成 JDBC Statement 所需要的参数。
ResultSetHandler负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。
TypeHandler负责 java 数据类型和 jdbc 数据类型之间的映射和转换。
MappedStatementMappedStatement 维护了一条<selectupdatedeleteinsert>节点的封装。
SqlSource负责根据⽤户传递的 parameterObject,动态地⽣成 SQL 语句,将信息封装到 BoundSql 对象中,并返回。
BoundSql表示动态⽣成的 SQL 语句以及相应的参数信息。

MyBatis 的层次结构

如图:从顶层 API 至底层的 JDBC

总体流程

  1. 加载配置文件并进行初始化
*  配置文件的来源有两个地方:一个是主配置文件 conf.xml、mapper文件*;另一个是代码中的注解。
*  将主配置文件内容解析封装到 Configuration,将 sql 的配置信息加载成为一个 mappedStatement 对象,存储在内存中。
  1. 接受调用请求
* 触发条件:调用 MyBatis 提供的 API
* 传入参数:SQL 的 ID 和传入的参数对象
* 处理过程:将请求传递给下层的请求处理层进行处理
  1. 处理操作请求
* 触发条件:API 接口层传递请求过来
* 传入参数:为 SQL 的 id 和 传入参数对象
* 处理过程:
    1. 根据 SQL 的 id 查找对应的 MappedStatement 对象
    2. 根据传入参数对象解析成 MappedStatement 对象,得到最终要执行的 SQL 和执行传入参数
    3. 获取数据库连接,根据得到的最终 SQL 语句和执行传入参数到数据库执行,并得到执行结果
    4. 根据 MappedStatement 对象中的结果映射配置,对得到的执行结果进行转换处理,并得到最终的处理结果
    5. 释放连接资源