Mybatis 都有哪些 Executor 执行器?
2026年01月07日
一则或许对你有用的小广告
欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于
Spring AI + Spring Boot3.x + JDK 21..., 点击查看; - 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot3.x + JDK 17..., 点击查看项目介绍; 演示链接: http://116.62.199.48:7070/; - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
面试考察点
这道题考察候选人对 MyBatis 核心执行引擎的掌握深度。面试官不仅仅是问 “有哪些”,更想了解:
- 源码级别的理解:是否清楚每种执行器对应的具体实现类及其在源码中的组织方式。
- 配置与实现的映射关系:能否区分 “配置值”(
SIMPLE)和 “实现类”(SimpleExecutor)的不同含义及它们如何关联。 - 核心工作机制差异:重点考察对三种执行器在
Statement管理策略上的根本区别的理解。 - 架构设计模式的应用:是否理解
CachingExecutor作为装饰器的设计模式应用及其与基础执行器的关系。 - 实践调优能力:能否根据不同业务场景(高频查询 vs 批量写入)选择合适的执行器进行性能优化。
核心答案
MyBatis 有三种核心的 Executor 实现类和一种装饰器类:
1. 核心实现类:
SimpleExecutor:默认执行器,每次执行都创建新的PreparedStatement。ReuseExecutor:重用执行器,缓存相同的SQL对应的PreparedStatement。BatchExecutor:批处理执行器,将多个更新操作合并批量执行。
2. 装饰器类:
CachingExecutor:二级缓存装饰器,为上述任意执行器添加缓存功能。
在配置时,我们使用对应的 ExecutorType 枚举值:SIMPLE、REUSE、BATCH,MyBatis 会根据这些值实例化相应的类。
深度解析
类名与配置值的映射机制
这是理解 MyBatis 执行器的关键。SimpleExecutor、ReuseExecutor、BatchExecutor 是具体的实现类,位于 org.apache.ibatis.executor 包中。而我们在配置中使用的 SIMPLE、REUSE、BATCH 是 ExecutorType 枚举的常量值,它们通过一个简单的工厂逻辑映射到具体的类:
// 简化版源码逻辑(org.apache.ibatis.session.Configuration)
public Executor newExecutor(ExecutorType executorType) {
Executor executor;
switch (executorType) {
case BATCH:
executor = new BatchExecutor(this, transaction);
break;
case REUSE:
executor = new ReuseExecutor(this, transaction);
break;
default: // 包括 SIMPLE 和未指定时
executor = new SimpleExecutor(this, transaction);
break;
}
// 如果开启了二级缓存,用 CachingExecutor 进行包装
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
return executor;
}
三种核心执行器的核心区别
| 执行器 | 核心机制 | Statement 管理策略 | 适用场景 |
|---|---|---|---|
SimpleExecutor | 每次执行新建 | 执行后立即关闭 | 通用场景,默认选择 |
ReuseExecutor | SQL 语句级缓存 | 缓存相同 SQL 的 Statement,会话结束时关闭 | 短时内高频执行相同 SQL |
BatchExecutor | 批量操作累积 | 缓存更新操作的 Statement,手动触发执行 | 大批量数据写入或更新 |
CachingExecutor 的特殊角色
它不是与前三者并列的第四种执行器,而是装饰器模式的典型应用。当 MyBatis 配置中开启二级缓存时,会自动用 CachingExecutor 包装你选择的实际执行器:
- 结构:
CachingExecutor持有delegate(可能是SimpleExecutor、ReuseExecutor或BatchExecutor) - 行为:执行查询时,先查二级缓存 → 命中则返回 → 未命中则委托给
delegate执行数据库查询 → 结果存入二级缓存
配置与使用示例
<!-- mybatis-config.xml 中配置默认执行器类型 -->
<settings>
<!-- 注意这里写的是枚举值,不是类名 -->
<setting name="defaultExecutorType" value="BATCH"/>
</settings>
// 编程式指定执行器类型(优先级高于配置)
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
UserMapper mapper = session.getMapper(UserMapper.class);
for (int i = 0; i < 1000; i++) {
mapper.insert(new User("user" + i));
}
// 必须显式提交,BatchExecutor 才会执行批量操作
session.commit();
}
常见误区与最佳实践
- 误区1:认为
CachingExecutor是独立的基础执行器。实际上它只是装饰层。 - 误区2:在
BatchExecutor中忘记调用commit()或flushStatements(),导致操作未执行。 - 误区3:在任何场景下都使用
ReuseExecutor。实际上长时间不关闭的SqlSession使用ReuseExecutor可能导致Statement缓存泄漏。 - 最佳实践:常规业务使用默认的
SimpleExecutor;数据导入等场景使用BatchExecutor;只有确认存在大量相同 SQL 重复执行时,才考虑使用ReuseExecutor。
总结
理解 MyBatis 执行器的关键是:区分配置枚举(SIMPLE)与实现类(SimpleExecutor)的对应关系,掌握三种基础执行器对 Statement 的不同管理策略,并明确 CachingExecutor 作为装饰器的特殊角色。这在面试中能体现出对 MyBatis 架构设计的深入理解。