mybatis源码-深入理解mybatis各个核心组件的作用和协作方式

107 阅读3分钟

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!


一、MyBatis 核心组件及其职责

组件核心职责关键类/接口
SqlSessionFactoryBuilder解析全局配置文件(mybatis-config.xml),构建 SqlSessionFactory 实例XMLConfigBuilder, SqlSessionFactoryBuilder
SqlSessionFactory创建 SqlSession 的工厂类,持有全局配置信息(ConfigurationDefaultSqlSessionFactory
SqlSession用户操作数据库的入口,封装 CRUD 方法,管理事务和连接生命周期DefaultSqlSession
Executor执行 SQL 的核心组件,处理缓存、事务、批处理等逻辑BaseExecutor(抽象基类)、SimpleExecutorReuseExecutorBatchExecutorCachingExecutor(二级缓存)
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插件机制的核心,通过动态代理拦截目标对象(如 ExecutorStatementHandlerInterceptor, 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),实现功能扩展。

三、核心组件协作示例

场景:执行 SELECT 查询

  1. 用户调用 Mapper 接口方法

    User user = userMapper.getUserById(1);
    
  2. 动态代理拦截(MapperProxy)

    • MapperProxy 拦截方法调用,根据方法名找到对应的 MappedStatement
  3. SqlSession 委托执行

    • DefaultSqlSession 调用 Executor.query(),传递 MappedStatement 和参数。
  4. Executor 处理缓存

    • BaseExecutor 先查询一级缓存,若未命中则调用 doQuery()
    • CachingExecutor 处理二级缓存(若配置)。
  5. StatementHandler 执行 SQL

    • PreparedStatementHandler 预编译 SQL,通过 ParameterHandler 设置参数。
    • 执行 PreparedStatement.execute(),获取 ResultSet
  6. ResultSetHandler 映射结果

    • DefaultResultSetHandlerResultSet 转换为 User 对象(利用 TypeHandler)。
  7. 返回结果

    • 结果逐级返回至 SqlSession,最终返回给用户。

四、设计模式与组件协作

设计模式应用场景实现类
工厂模式创建 SqlSessionExecutor 等对象SqlSessionFactory, ExecutorType
动态代理模式实现 Mapper 接口的代理类(MapperProxyMapperProxy, Plugin
模板方法模式BaseExecutor 定义执行流程,子类实现具体逻辑BaseExecutor.query()SimpleExecutor.doQuery()
装饰器模式CachingExecutor 包装普通 Executor 添加二级缓存CachingExecutor 持有 Executor 的引用
责任链模式插件拦截器链(InterceptorChainInterceptorChain.pluginAll()

五、高级协作场景

1. 插件机制(Interceptor)

  • 协作流程

image.png

  • 示例:分页插件通过拦截 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通过插件和类型处理器增强功能(如分页、加密)