MyBatis 的运行原理可以概括为以下几个核心步骤:
1. 加载配置:
- MyBatis 首先会读取核心配置文件(通常是
mybatis-config.xml),或者通过 Java 代码创建配置对象Configuration。 - 核心配置文件中包含了 MyBatis 的全局配置信息,如数据源、事务管理器、类型别名、类型处理器、插件、映射器等。
2. 构建 SqlSessionFactory:
- MyBatis 使用
SqlSessionFactoryBuilder根据配置信息(Configuration对象)构建SqlSessionFactory。 SqlSessionFactory是一个工厂类,负责创建SqlSession对象。SqlSessionFactory通常在应用程序的生命周期内只需要创建一个实例(单例模式)。
3. 打开 SqlSession:
- 通过
SqlSessionFactory的openSession()方法打开一个新的SqlSession。 SqlSession代表与数据库的一次会话,它包含了执行 SQL 语句、获取 Mapper 接口实例、管理事务等方法。SqlSession不是线程安全的,每个线程应该拥有自己的SqlSession实例。
4. 获取 Mapper 接口的代理对象 (推荐方式):
- 通过
SqlSession的getMapper()方法获取 Mapper 接口的代理对象。 - MyBatis 使用动态代理技术(JDK 动态代理或 CGLIB)创建 Mapper 接口的代理对象。
5. 执行 Mapper 接口方法:
- 当调用 Mapper 接口的方法时,实际上调用的是 MyBatis 生成的代理对象的方法。
- 代理对象会根据以下信息查找对应的
MappedStatement对象:- Namespace: Mapper 接口的全限定名,用于确定 SQL 映射文件。
- Statement ID: Mapper 接口的方法名,用于确定 SQL 映射文件中的具体 SQL 语句。
6. 查找 MappedStatement:
MappedStatement对象代表一个 SQL 语句(<select>,<insert>,<update>,<delete>),它包含了 SQL 语句的 ID、参数类型、结果类型、SQL 语句内容等信息。MappedStatement对象在 MyBatis 初始化时(构建SqlSessionFactory时)就已经被解析并保存在Configuration对象中。
7. 创建执行器 (Executor):
- MyBatis 根据配置信息(例如,
defaultExecutorType设置)创建Executor对象。 Executor负责执行 SQL 语句,并处理缓存(一级缓存和二级缓存)。- MyBatis 支持三种类型的
Executor:SIMPLE: 每次执行 SQL 语句都会创建一个新的PreparedStatement。REUSE: 重复使用PreparedStatement,只要 SQL 语句和参数类型相同,就会使用同一个PreparedStatement。BATCH: 批量执行 SQL 语句,将多个 SQL 语句攒起来一次性发送到数据库执行。
8. 创建语句处理器 (StatementHandler):
- MyBatis 根据
MappedStatement和Executor创建StatementHandler对象。 StatementHandler负责处理 JDBC 的Statement(或PreparedStatement),包括设置参数、执行 SQL 语句、处理结果集等。- MyBatis 支持三种类型的
StatementHandler:SimpleStatementHandler: 处理普通的Statement。PreparedStatementHandler: 处理PreparedStatement。CallableStatementHandler: 处理存储过程调用。
9. 创建参数处理器 (ParameterHandler):
- MyBatis 根据
MappedStatement创建ParameterHandler对象。 ParameterHandler负责将 Java 方法的参数转换为 JDBC 类型,并设置到PreparedStatement的占位符中。ParameterHandler会使用TypeHandler进行类型转换。
10. 执行 SQL 语句:
StatementHandler使用PreparedStatement执行 SQL 语句。
11. 创建结果集处理器 (ResultSetHandler):
- MyBatis 根据
MappedStatement创建ResultSetHandler对象。 ResultSetHandler负责将 JDBC 的ResultSet转换为 Java 对象。ResultSetHandler会使用TypeHandler进行类型转换。
12. 结果映射:
ResultSetHandler将ResultSet中的数据映射为 Java 对象(或 Map、List 等)。- MyBatis 支持多种结果映射方式,包括自动映射、
resultType、<resultMap>、关联映射、鉴别器等。
13. 返回结果:
ResultSetHandler将映射后的 Java 对象返回给Executor。Executor将结果返回给SqlSession。SqlSession将结果返回给 Mapper 接口的代理对象。- 代理对象将结果返回给调用者。
14. 提交或回滚事务 (如果需要):
- 如果进行了数据库修改操作(
insert、update、delete),需要手动提交事务(commit())或回滚事务(rollback())。 - 如果只进行了查询操作(
select),则不需要。
15. 关闭 SqlSession:
- 使用
SqlSession的close()方法关闭会话,释放资源。 - 务必在
finally块中关闭SqlSession,以确保资源被正确释放。
流程图:
[Client Code] --> [Mapper Interface] --> [Mapper Proxy (Dynamic Proxy)] --> [SqlSession] --> [Executor] --> [StatementHandler] --> [ParameterHandler] + [ResultSetHandler] --> [JDBC (PreparedStatement)] --> [Database]
^
|
[TypeHandler] (参数转换和结果转换)
^
|
[MappedStatement] (包含 SQL 语句、参数类型、结果类型等信息)
^
|
[Configuration] (全局配置信息)
总结:
MyBatis 的运行原理可以概括为:加载配置、构建 SqlSessionFactory、打开 SqlSession、获取 Mapper 接口代理对象、执行 Mapper 接口方法、查找 MappedStatement、创建执行器、创建语句处理器、创建参数处理器、执行 SQL 语句、创建结果集处理器、结果映射、返回结果、提交/回滚事务、关闭 SqlSession。 MyBatis 通过动态代理、反射、类型转换、缓存等技术,实现了 SQL 语句与 Java 代码的解耦,简化了数据库访问操作。

2127

被折叠的 条评论
为什么被折叠?



