MyBatis的Executor有三种基础实现:SimpleExecutor默认每次创建新Statement,适合低频、动态SQL场景;ReuseExecutor按SQL字符串缓存PreparedStatement,提升高频固定SQL查询效率;BatchExecutor仅支持DML批量操作,通过addBatch/executeBatch优化写性能。

MyBatis 的 Executor 是负责 SQL 执行的核心组件,它决定了 SQL 语句如何被预编译、缓存、复用以及是否批量提交。官方提供了三种基础实现类,对应三种执行器类型:SimpleExecutor、ReuseExecutor 和 BatchExecutor。
SimpleExecutor:默认、最简单,适合单次操作
每次执行 SQL 都会创建全新的 Statement(或 PreparedStatement),用完即关,不复用也不缓存。无状态、线程安全,但开销略大。
- 适用于查询/更新频率低、SQL 动态性强(如含大量拼接条件)、或需严格隔离执行上下文的场景
- Spring 整合 MyBatis 时,默认使用的就是 SimpleExecutor(除非显式配置)
- 不会因 Statement 复用导致参数残留或结果错乱,调试友好
ReuseExecutor:复用 PreparedStatement,适合重复 SQL
按 SQL 语句字符串为 key 缓存 PreparedStatement 对象,相同 SQL 多次执行时可复用已编译的 Statement,减少数据库端解析开销。
- 适合固定 SQL 模板高频调用(如根据 ID 查询用户:
SELECT * FROM user WHERE id = ?) - 注意:SQL 字符串必须完全一致(包括空格、换行、大小写)才命中缓存;动态 SQL(如
<if>)易导致缓存碎片化 - 不适用于 DML 批量操作,因为复用的 PreparedStatement 无法自动累积执行
BatchExecutor:批量执行,专为 insert/update/delete 优化
将多个相同类型的 DML 语句(如多条 INSERT)暂存于本地队列,统一调用 JDBC 的 addBatch() + executeBatch() 提交,显著降低网络往返和事务开销。
立即学习“Java免费学习笔记(深入)”;
- 仅支持
UPDATE、INSERT、DELETE,不支持 SELECT(调用查询会强制 flush 并退化为 Simple 执行) - 必须配合
SqlSession的非自动提交模式(autoCommit=false)使用,否则每 commit 一次就清空 batch - 实际性能提升依赖数据库驱动对批量的支持程度(如 MySQL 需开启
rewriteBatchedStatements=true参数才真正合并)
怎么选?看场景,不看名字
选择不是靠“哪个高级”,而是匹配真实负载特征:
- 读多写少、SQL 差异大、强调稳定性 → 用 SimpleExecutor(默认最稳妥)
- 写操作频繁且 SQL 模板高度统一(如日志表批量插入固定字段)→ 尝试 BatchExecutor,并验证数据库侧是否生效
- 存在大量相同结构的单条查询(尤其在循环中反复查同一条语句)→ 可评估 ReuseExecutor,但优先考虑一级/二级缓存或应用层缓存
- 全局切换通过
<settings><setting name="defaultExecutorType" value="BATCH"/></settings>配置;也可在 openSession 时传入ExecutorType.BATCH


















