mybatis 中真正参与 sql 执行的 executor 主要有 simpleexecutor、reuseexecutor 和 batchexecutor 三种:simpleexecutor 每次新建 preparedstatement,适合常规场景;reuseexecutor 缓存 preparedstatement,适用于高频固定 sql;batchexecutor 专为批量写操作优化,需手动刷新。

MyBatis 中真正参与 SQL 执行的 Executor 主要有三种:SimpleExecutor、ReuseExecutor 和 BatchExecutor。CachingExecutor 不是独立类型,而是装饰器,会在开启二级缓存时自动包裹上述任一执行器,不参与直接选择。
SimpleExecutor:默认且最稳妥的选择
每次执行 SQL 都新建 PreparedStatement,用完即关,不复用也不缓存语句。它逻辑清晰、行为可预测,适合绝大多数常规场景。
- 同一 SqlSession 内仍支持一级缓存(基于 MappedStatement + 参数的哈希匹配)
- 无需担心 Statement 复用带来的连接状态或参数残留问题
- 调试友好,每条 SQL 的执行过程彼此隔离
- 适用于查询为主、SQL 多样、并发不高或对一致性要求严格的业务
ReuseExecutor:适合高频重复 SQL
按 SQL 字符串精确匹配缓存 PreparedStatement,相同语句(注意:空格、换行、注释差异都会导致不命中)只编译一次,后续仅重设参数执行。
- 能降低 JDBC 驱动的 SQL 解析与预编译开销
- 缓存作用域限于当前 SqlSession,不会跨会话共享
- 不适用于动态 SQL 变化频繁的场景(如大量
<if></if>拼接) - 适合固定条件查询,比如“根据用户 ID 查订单”这类高频、结构稳定的语句
BatchExecutor:专为批量写操作优化
只对 INSERT/UPDATE/DELETE 生效,将多条同类型语句暂存,调用 flushStatements() 或 commit() 时统一提交。SELECT 不走批处理流程。
- 显著减少网络往返和 JDBC 驱动开销
- 必须手动刷新(
sqlSession.flushStatements())或提交事务才能真正执行 - 不支持 SELECT,也不能在同一个 SqlSession 中混用 SELECT 和批量 UPDATE
- 适合数据导入、日志归档、批量同步等后台任务
怎么选:看操作类型和执行频率
选择不是靠配置项堆叠,而是结合具体使用方式:
- 日常开发、CRUD 混合、不确定 SQL 结构是否稳定 → 用默认 SimpleExecutor
- 监控发现某几条固定 SQL 占比极高且耗时集中在 prepare 阶段 → 尝试 ReuseExecutor
- 明确要插入/更新上千条记录,且无实时性要求 → 创建 SqlSession 时指定
ExecutorType.BATCH - 二级缓存已开启 → 不用额外选 CachingExecutor,它会自动生效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











