知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!
一、MyBatis 核心组件及其职责
| 组件 | 核心职责 | 关键类/接口 |
|---|---|---|
| SqlSessionFactoryBuilder | 解析全局配置文件(mybatis-config.xml),构建 SqlSessionFactory 实例 | XMLConfigBuilder, SqlSessionFactoryBuilder |
| SqlSessionFactory | 创建 SqlSession 的工厂类,持有全局配置信息(Configuration) | DefaultSqlSessionFactory |
| SqlSession | 用户操作数据库的入口,封装 CRUD 方法,管理事务和连接生命周期 | DefaultSqlSession |
| Executor | 执行 SQL 的核心组件,处理缓存、事务、批处理等逻辑 | BaseExecutor(抽象基类)、SimpleExecutor、ReuseExecutor、BatchExecutor、CachingExecutor(二级缓存) |
| MappedStatement | 封装 SQL 语句的元数据(如 SQL 文本、参数映射、结果映射) | MappedStatement |
| StatementHandler | 处理 JDBC Statement(如预编译、参数填充、执行 SQL) | PreparedStatementHandler, SimpleStatementHandler, CallableStatementHandler |
| ParameterHandler | 将 Java 对象转换为 SQL 参数(处理 #{} 占位符) | DefaultParameterHandler |
| ResultSetHandler | 将 JDBC ResultSet 转换为 Java 对象(结果集映射) | DefaultResultSetHandler |
| TypeHandler | 处理 Java 类型与 JDBC 类型之间的转换(如日期、枚举) | BaseTypeHandler, StringTypeHandler, IntegerTypeHandler 等 |
| Interceptor | 插件机制的核心,通过动态代理拦截目标对象(如 Executor、StatementHandler) | Interceptor, InterceptorChain |
| Configuration | 全局配置中心,存储所有配置信息(数据源、Mapper、插件等) | Configuration |
二、核心组件协作流程
1. 配置加载阶段
graph TD
A[SqlSessionFactoryBuilder] --> B[解析 mybatis-config.xml]
B --> C[构建 Configuration 对象]
C --> D[创建 SqlSessionFactory]
- 关键协作:
SqlSessionFactoryBuilder使用XMLConfigBuilder解析配置文件。Configuration对象存储数据源、插件、Mapper 等信息。- 最终生成
SqlSessionFactory(如DefaultSqlSessionFactory)。
2. Mapper 接口绑定阶段
graph TD
A[Mapper 接口] --> B[MapperProxy 动态代理]
B --> C[关联 MappedStatement]
C --> D[注册到 Configuration]
- 关键协作:
MapperRegistry管理 Mapper 接口与动态代理工厂(MapperProxyFactory)的绑定。MapperAnnotationBuilder解析接口上的注解(如@Select)生成MappedStatement。
3. SQL 执行阶段
sequenceDiagram
participant Client
participant MapperProxy
participant SqlSession
participant Executor
participant StatementHandler
participant JDBC
Client->>MapperProxy: 调用接口方法
MapperProxy->>SqlSession: 获取 SqlSession
SqlSession->>Executor: 委托执行
Executor->>StatementHandler: 创建 Statement
StatementHandler->>JDBC: 执行 SQL
JDBC-->>StatementHandler: 返回 ResultSet
StatementHandler-->>Executor: 处理结果
Executor-->>SqlSession: 返回结果
SqlSession-->>Client: 返回数据
- 关键协作:
- Executor:决定是否走缓存(一级缓存
PerpetualCache或二级缓存CachingExecutor)。 - StatementHandler:与
ParameterHandler协作设置参数,与ResultSetHandler协作处理结果。 - 插件机制:通过
InterceptorChain包装目标对象(如Executor),实现功能扩展。
- Executor:决定是否走缓存(一级缓存
三、核心组件协作示例
场景:执行 SELECT 查询
-
用户调用 Mapper 接口方法:
User user = userMapper.getUserById(1); -
动态代理拦截(MapperProxy):
MapperProxy拦截方法调用,根据方法名找到对应的MappedStatement。
-
SqlSession 委托执行:
DefaultSqlSession调用Executor.query(),传递MappedStatement和参数。
-
Executor 处理缓存:
BaseExecutor先查询一级缓存,若未命中则调用doQuery()。CachingExecutor处理二级缓存(若配置)。
-
StatementHandler 执行 SQL:
PreparedStatementHandler预编译 SQL,通过ParameterHandler设置参数。- 执行
PreparedStatement.execute(),获取ResultSet。
-
ResultSetHandler 映射结果:
DefaultResultSetHandler将ResultSet转换为User对象(利用TypeHandler)。
-
返回结果:
- 结果逐级返回至
SqlSession,最终返回给用户。
- 结果逐级返回至
四、设计模式与组件协作
| 设计模式 | 应用场景 | 实现类 |
|---|---|---|
| 工厂模式 | 创建 SqlSession、Executor 等对象 | SqlSessionFactory, ExecutorType |
| 动态代理模式 | 实现 Mapper 接口的代理类(MapperProxy) | MapperProxy, Plugin |
| 模板方法模式 | BaseExecutor 定义执行流程,子类实现具体逻辑 | BaseExecutor.query() → SimpleExecutor.doQuery() |
| 装饰器模式 | CachingExecutor 包装普通 Executor 添加二级缓存 | CachingExecutor 持有 Executor 的引用 |
| 责任链模式 | 插件拦截器链(InterceptorChain) | InterceptorChain.pluginAll() |
五、高级协作场景
1. 插件机制(Interceptor)
- 协作流程:
- 示例:分页插件通过拦截
StatementHandler.prepare(),重写 SQL 添加LIMIT子句。
2. 二级缓存(CachingExecutor)
- 协作流程:
CachingExecutor包装BaseExecutor,优先查询二级缓存。- 缓存命中:直接返回结果;未命中:委托给底层 Executor 执行查询,并缓存结果。
3. 批量处理(BatchExecutor)
- 协作流程:
BatchExecutor缓存多个Statement,在commit时一次性执行。- 通过
addBatch()收集 SQL,flushStatements()批量提交。
六、组件协作总结
| 阶段 | 核心组件 | 协作目标 |
|---|---|---|
| 配置加载 | SqlSessionFactoryBuilder | 解析全局配置,构建 Configuration 和 SqlSessionFactory |
| Mapper 绑定 | MapperProxy, MapperRegistry | 将接口方法与 SQL 绑定,生成 MappedStatement |
| SQL 执行 | Executor, StatementHandler | 处理缓存、执行 SQL、映射结果 |
| 扩展机制 | Interceptor, TypeHandler | 通过插件和类型处理器增强功能(如分页、加密) |