executor 是总控,statementhandler 是具体执行者:executor 负责缓存、策略选择、连接获取及任务派发;statementhandler 专注 sql 预编译、参数绑定与 jdbc 执行。

StatementHandler 和 Executor 在 MyBatis 中是上下协作关系,不是并列分工,而是“执行器调度,语句处理器落地”——Executor 是总控,StatementHandler 是具体干活的。
Executor:负责整体流程与决策
它不直接操作数据库,而是统筹全局:
- 先查一级缓存,命中就跳过后续步骤,直接返回结果
- 决定用哪种执行策略(Simple/Reuse/Batch/Caching)
- 获取数据库连接(委托 Transaction 管理)
- 创建 StatementHandler、ParameterHandler、ResultSetHandler 实例
- 把 SQL 执行任务“派发”给 StatementHandler,并接收其返回结果
- 事务提交或回滚,以及二级缓存写入(CachingExecutor 场景)
StatementHandler:专注 SQL 的 JDBC 层执行
它拿到 Executor 派发的任务后,专注把一条 SQL 真正跑起来:
- 根据 MappedStatement 中的 SQL 类型(普通语句、预编译、存储过程),创建对应 Statement(如 PreparedStatement)
- 调用 ParameterHandler 绑定参数(比如把 #{id} 替换成 1)
- 设置超时时间、fetchSize、重试逻辑等执行参数
- 真正调用 JDBC 的 executeQuery() 或 executeUpdate()
- 把执行后的 ResultSet 交给 ResultSetHandler 映射成 Java 对象
一个 selectById(1) 的典型协作链
当你调用 userMapper.selectById(1) 时:
- Executor 先检查一级缓存中是否有 key=id:1 的结果;有则直接返回
- 没有则调用 StatementHandler.prepare():创建 PreparedStatement,SQL 是 "SELECT * FROM user WHERE id = ?"
- 再调用 StatementHandler.parameterize():把参数 1 设置进 PreparedStatement 的第一个 ?
- 再调用 StatementHandler.query():执行 JDBC 查询,拿到 ResultSet
- ResultSetHandler 接手,将 ResultSet 每一行转成 User 对象,最终由 Executor 封装为 List 返回
插件拦截的关键位置也体现分工
如果你写 MyBatis 插件:
- 想改 SQL 文本或控制查询是否执行 → 拦截 Executor#query/update
- 想改参数绑定逻辑或自定义 Statement 创建 → 拦截 StatementHandler#prepare/parameterize
- 想修改结果映射行为 → 拦截 ResultSetHandler#handleResultSets
简单说:Executor 像项目经理,管计划、资源、缓存和事务;StatementHandler 像开发工程师,只管把指定 SQL 安全、正确、高效地跑通 JDBC 这一关。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











