非常棒的问题 👍,MyBatis 的源码流程可以从 一次 SQL 执行的生命周期 来解析。整体上它是一个 半自动 ORM 框架,主要解决:SQL 映射 → 参数处理 → 执行 SQL → 结果映射。
我帮你分三部分讲清楚:整体架构 → 执行流程 → 核心源码关键点。
1. MyBatis 架构核心
MyBatis 核心组件:
- SqlSessionFactory:会话工厂(创建 SqlSession)
- SqlSession:一次数据库会话(执行 SQL 的入口)
- Executor:执行器(负责执行 SQL,维护一级缓存)
- StatementHandler:封装 JDBC Statement 的操作
- ParameterHandler:负责处理 SQL 参数
- ResultSetHandler:负责结果集的映射
- MapperProxy:动态代理接口,实现方法到 SQL 的映射
2. 执行流程(整体步骤)
以执行一次 userMapper.selectUserById(1) 为例:
1. 初始化├─ SqlSessionFactoryBuilder → 构建 SqlSessionFactory└─ SqlSessionFactory → 解析 XML/注解,构建 Configuration2. 获取 SqlSession└─ SqlSessionFactory.openSession() → 创建 DefaultSqlSession3. Mapper 动态代理└─ UserMapper mapper = sqlSession.getMapper(UserMapper.class)(生成 MapperProxy 代理对象)4. 执行 SQL├─ mapper.selectUserById(1)├─ MapperProxy.invoke() → 根据方法找到 MappedStatement└─ SqlSession.selectOne(mappedStatement, params)5. Executor 执行├─ CachingExecutor (二级缓存) → delegate → SimpleExecutor├─ 创建 StatementHandler├─ ParameterHandler 设置参数├─ JDBC PreparedStatement 执行 SQL└─ ResultSetHandler 映射结果6. 返回结果
3. 源码关键点
(1) SqlSessionFactory 初始化
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
- 读取配置文件(mybatis-config.xml)
- 解析
<mappers>、<environments>等标签 - 构建全局的 Configuration 对象(保存所有 SQL 映射、数据源配置、类型别名、插件等)
(2) Mapper 动态代理
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
-
生成
MapperProxy动态代理对象 -
方法调用时会进入
MapperProxy.invoke()- 根据接口方法找到
MappedStatement(SQL + 参数映射 + 结果映射) - 调用
sqlSession.selectOne()或selectList()
- 根据接口方法找到
(3) SqlSession → Executor
以 selectList() 为例:
public <E> List<E> selectList(String statement, Object parameter) {MappedStatement ms = configuration.getMappedStatement(statement);return executor.query(ms, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
}
- 找到
MappedStatement(SQL 信息的封装对象) - 调用
Executor.query()
(4) Executor 执行链
Executor 有三种实现:
- SimpleExecutor:每次执行都新建 Statement
- ReuseExecutor:重用 Statement
- BatchExecutor:批处理 SQL
执行链一般是:
CachingExecutor (二级缓存装饰器)↓
BaseExecutor (一级缓存)↓
具体的 SimpleExecutor/ReuseExecutor/BatchExecutor
(5) StatementHandler
Executor 会创建一个 StatementHandler,用来处理 JDBC 语句:
StatementHandler handler = configuration.newStatementHandler(...);
StatementHandler 内部又包含:
- ParameterHandler:处理 SQL 占位符参数绑定
- ResultSetHandler:处理结果集映射
(6) JDBC 执行
handler.query(statement, resultHandler) →
parameterHandler.setParameters(ps):设置 PreparedStatement 参数ps.execute():执行 SQLresultSetHandler.handleResultSets(ps):映射结果
(7) 结果映射
ResultSetHandler:
- 遍历结果集
- 根据
ResultMap或@Results注解,将列映射到对象属性 - 支持嵌套映射(关联查询、集合映射)
4. 插件机制(重要)
MyBatis 提供了强大的 拦截器(Interceptor),可以拦截四大对象:
- Executor(执行 SQL)
- StatementHandler(处理 SQL)
- ParameterHandler(处理参数)
- ResultSetHandler(处理结果)
这是 MyBatis 的 AOP 扩展点,很多分页插件、监控插件就是基于它实现的。
5. 总结
一句话概括 MyBatis 源码流程:
SqlSession → MapperProxy → MappedStatement → Executor → StatementHandler → ParameterHandler → JDBC 执行 → ResultSetHandler → 返回结果。
