MyBatis 核心类详解与架构解析:从入门到源码级理解
引言
MyBatis 是一款轻量级的持久层框架,通过灵活的 SQL 映射和高效的执行机制,成为 Java 开发中的热门选择。要深入掌握 MyBatis 的工作原理,理解其核心类及其职责至关重要。本文将带你梳理 MyBatis 的关键类、初始化流程以及它们之间的协作关系,帮助你构建完整的 MyBatis 架构知识体系。
🧱 一、MyBatis 核心类概览
MyBatis 的核心类构成了其运行时的骨架,每个类都承担着特定的职责。以下是核心类的层级结构图:
SqlSessionFactoryBuilder↓
SqlSessionFactory (DefaultSqlSessionFactory)↓
SqlSession (DefaultSqlSession)↓
Executor↓
StatementHandler↓
ParameterHandler / TypeHandler / ResultSetHandler
📌 二、关键类职责详解
1. SqlSessionFactoryBuilder
- 包路径:
org.apache.ibatis.session.SqlSessionFactoryBuilder
- 职责:
- 使用建造者模式(Builder Pattern)构建
SqlSessionFactory
。 - 通过加载
mybatis-config.xml
配置文件或 Java API 方式创建Configuration
对象。
- 使用建造者模式(Builder Pattern)构建
- 特点:
- 是临时对象,通常在应用启动时使用一次后丢弃。
2. SqlSessionFactory
- 实现类:
DefaultSqlSessionFactory
- 包路径:
org.apache.ibatis.session.SqlSessionFactory
- 职责:
- 创建
SqlSession
实例。 - 包含全局唯一的
Configuration
实例,管理 MyBatis 的全局配置(如数据源、事务工厂、插件等)。
- 创建
- 特点:
- 线程安全,通常在应用生命周期内只初始化一次。
3. SqlSession
- 实现类:
DefaultSqlSession
- 包路径:
org.apache.ibatis.session.SqlSession
- 职责:
- 提供操作数据库的核心 API(如
selectList
,insert
,update
,delete
)。 - 是非线程安全的,每次请求应使用独立的
SqlSession
实例。
- 提供操作数据库的核心 API(如
- 底层依赖:
- 通过
Executor
执行 SQL 操作。
- 通过
4. Executor
- 实现类:
SimpleExecutor
,ReuseExecutor
,BatchExecutor
- 包路径:
org.apache.ibatis.executor.Executor
- 职责:
- SQL 执行引擎的核心,负责 SQL 的实际执行及缓存管理。
- 支持一级缓存(本地缓存)和二级缓存(跨 SqlSession 缓存)。
- 特点:
- 可通过拦截器(Interceptor)扩展功能(如分页、日志记录)。
5. MappedStatement
- 包路径:
org.apache.ibatis.mapping.MappedStatement
- 职责:
- 封装一条 SQL 映射信息,包括 SQL 语句、参数类型、结果映射等。
- 每个 XML 中的
<select>
、<update>
等标签或注解中的 SQL 对应一个MappedStatement
。
- 存储位置:
- 注册在
Configuration.mappedStatements
中。
- 注册在
6. Configuration
- 包路径:
org.apache.ibatis.session.Configuration
- 职责:
- MyBatis 全局配置的核心对象,包含数据库连接池、事务工厂、插件拦截器、语言驱动器等。
- 在初始化时由
SqlSessionFactoryBuilder
加载生成。
- 扩展点:
- 支持自定义
LanguageDriver
(如 Groovy、Velocity 模板引擎)。
- 支持自定义
7. StatementHandler
- 实现类:
RoutingStatementHandler
,SimpleStatementHandler
,PreparedStatementHandler
,CallableStatementHandler
- 包路径:
org.apache.ibatis.executor.statement.StatementHandler
- 职责:
- 封装 JDBC 的
Statement
、PreparedStatement
、CallableStatement
。 - 负责与 JDBC 层交互,执行 SQL。
- 封装 JDBC 的
- 扩展点:
- 可通过拦截器修改 SQL 或参数(如分页插件)。
8. ParameterHandler
- 实现类:
DefaultParameterHandler
- 包路径:
org.apache.ibatis.executor.parameter.ParameterHandler
- 职责:
- 将 Java 对象转换为 JDBC 类型并设置到
PreparedStatement
中。 - 依赖
TypeHandler
完成类型转换。
- 将 Java 对象转换为 JDBC 类型并设置到
9. TypeHandler
- 接口:
org.apache.ibatis.type.TypeHandler
- 职责:
- 实现 Java 类型与 JDBC 类型之间的双向转换。
- MyBatis 内置了常见类型的处理器(如 Integer、String),也支持自定义。
10. ResultSetHandler
- 实现类:
DefaultResultSetHandler
- 包路径:
org.apache.ibatis.executor.resultset.ResultSetHandler
- 职责:
- 处理 JDBC 查询返回的
ResultSet
,将其转换为 Java 对象。 - 支持一对一、一对多等复杂结果映射。
- 处理 JDBC 查询返回的
🧩 三、MyBatis 初始化流程解析
-
加载配置文件
- 通过
SqlSessionFactoryBuilder.build()
方法读取mybatis-config.xml
。 - 解析全局配置,构建
Configuration
对象。
- 通过
-
解析映射文件
- 加载 Mapper XML 文件或注解中的 SQL 映射信息。
- 将每条 SQL 封装为
MappedStatement
,注册到Configuration
中。
-
创建
SqlSessionFactory
- 返回
DefaultSqlSessionFactory
实例,包含完整的Configuration
。
- 返回
-
创建
SqlSession
- 调用
sqlSessionFactory.openSession()
创建SqlSession
。 SqlSession
内部持有Executor
实例。
- 调用
-
执行 SQL
- 通过
SqlSession
的 API(如selectList
)触发 SQL 执行。 - 流程:
Executor
→StatementHandler
→ JDBC →ParameterHandler
/ResultSetHandler
。
- 通过
🎯 四、设计模式与扩展性
MyBatis 的设计融合了多种经典设计模式,提升了灵活性和可扩展性:
- 建造者模式:
SqlSessionFactoryBuilder
负责构建SqlSessionFactory
。 - 工厂模式:
SqlSessionFactory
创建SqlSession
。 - 代理模式:Mapper 接口通过动态代理生成实现类。
- 模板方法模式:
Executor
的执行流程定义了骨架,具体步骤由子类实现。
扩展点示例:
- 自定义
LanguageDriver
支持 Groovy、Velocity 等脚本语言。 - 通过拦截器(Interceptor)增强 SQL 执行逻辑(如分页、日志、权限控制)。
- 自定义
TypeHandler
处理复杂类型转换(如 JSON、枚举)。
📚 五、总结与进阶建议
核心类职责一览表
类名 | 职责简述 |
---|---|
SqlSessionFactoryBuilder | 构建 SqlSessionFactory |
SqlSessionFactory | 创建 SqlSession |
SqlSession | 提供数据库操作 API |
Executor | SQL 执行引擎 |
MappedStatement | 单条 SQL 的封装 |
Configuration | 全局配置管理器 |
StatementHandler | JDBC Statement 操作 |
ParameterHandler | 设置 SQL 参数 |
TypeHandler | Java 与 JDBC 类型转换 |
ResultSetHandler | 结果集处理 |
进阶学习方向
- 插件开发:研究拦截器机制,实现自定义插件(如审计日志、性能监控)。
- 缓存机制:深入理解一级缓存、二级缓存的实现原理。
- 动态 SQL:分析 XMLLanguageDriver 如何解析
<if>
,<foreach>
等标签。 - 懒加载:探索关联对象延迟加载的实现细节。