手写MyBatis ORM框架(六)

手写MyBatis ORM框架(六)

引言

上一部分我们创建了数据库连接池,这个连接池指定是我们在执行SQL的时候才用到的,这一部分我们就实现这个。

开始

Executor 的作用

1. SQL 执行调度

  • 核心职责Executor 是 MyBatis 执行 SQL 的入口,负责调用底层组件(如 StatementHandlerParameterHandlerResultSetHandler)完成以下流程:

    • 解析 MappedStatement(映射语句配置)。

    • 获取数据库连接。

    • 设置 SQL 参数。

    • 执行 SQL。

    • 处理结果集映射。

  • 统一接口: 提供 update()query() 方法,统一处理增删改和查询操作。

2. 缓存管理

  • 一级缓存(本地缓存)

    • 默认开启,基于 SqlSession 生命周期,缓存相同 SQL 和参数的查询结果。

    • Executor 管理缓存的写入和失效(如执行更新操作后清空缓存)。

  • 二级缓存(全局缓存)

    • SqlSession 共享,需在映射文件中显式配置 <cache>

    • Executor 通过 CachingExecutor 装饰器实现二级缓存的读写。

3. 事务管理

  • 连接生命周期

    • 负责从 Transaction 对象获取数据库连接。

    • 在事务提交或回滚时,调用 Transactioncommit()rollback()

  • 事务边界控制

    • 确保多个数据库操作在同一个事务中执行(通过 SqlSessioncommit()rollback() 触发)。

4. 延迟加载(Lazy Loading)

  • 代理对象生成

    • 对关联对象(如 associationcollection)生成代理类。

    • 在首次访问关联对象时,通过 Executor 触发二次查询。

  • 执行控制: 延迟加载的查询由 Executor 动态调度,确保按需加载。

5. 批处理优化

  • 批量操作支持

    • 通过 BatchExecutor 实现批量提交 SQL,减少网络开销。

    • 示例:批量插入 1000 条数据时,合并为一次 JDBC 批量执行。


Executor 的核心实现类

MyBatis 提供了多种 Executor 实现,适用于不同场景:

​实现类

​特点

SimpleExecutor

​默认实现,每次执行 SQL 后关闭 Statement 对象,无复用。

ReuseExecutor

​重用预处理语句,缓存同一 SQL 的 PreparedStatement,减少解析开销。

BatchExecutor

​批量模式,将多个更新操作合并提交,提升批量任务性能。

CachingExecutor

​装饰器模式,为其他 Executor 添加二级缓存支持。

配置方式

在 MyBatis 全局配置中指定默认执行器类型:

xml

<configuration>
  <settings>
    <setting name="defaultExecutorType" value="SIMPLE"/> <!-- 可选 SIMPLE, REUSE, BATCH -->
  </settings>
</configuration>

执行器的定义和实现

这些我们之前定义的事务方法,就会用到我们的执行器之中。

创建Executor

我们在执行器中定义的接口包括事务相关的处理方法和执行SQL查询的操作。

在抽象基类中封装了执行器的全部接口,这样具体的子类继承抽象类后,就不用在处理这些共性的方法。这就用到了模板方法设计模式了,与此同时在 query 查询方法中,我们先不去实现缓存设计这些。

Todo

ReuseExecutor

BatchExecutor

LICENSED UNDER CC BY-NC-SA 4.0