MyBatis 是一个半自动化的持久层框架,它通过配置文件或注解将 SQL 语句与 Java 对象进行映射,从而简化数据库访问操作。MyBatis 的执行原理涉及多个核心组件和步骤,以下是对 MyBatis 执行原理的详细说明:
1. MyBatis 的核心组件
-
SqlSessionFactory
:用于创建SqlSession
对象的工厂。它是 MyBatis 框架的核心,负责读取配置文件和管理 MyBatis 的资源。 -
SqlSession
:表示与数据库交互的会话。通过SqlSession
,开发者可以执行 SQL 语句、获取映射的 Java 对象、管理事务等。SqlSession
不是线程安全的,通常应该在方法中创建并使用,使用后立即关闭。 -
Executor
:MyBatis 中的执行器,负责执行映射语句、调用映射器(Mapper)接口方法、处理缓存等。Executor
是 MyBatis 内部执行 SQL 的核心组件。 -
MappedStatement
:表示 MyBatis 中的映射语句(如<select>
、<insert>
、<update>
、<delete>
)。每个映射语句对应一个MappedStatement
对象,它包含了执行 SQL 所需的全部信息。 -
Configuration
:全局配置类,包含了 MyBatis 的所有配置,如环境信息、映射器(Mapper)信息、类型处理器、插件等。 -
Cache
:MyBatis 中的缓存机制。MyBatis 提供了一级缓存(默认开启,基于SqlSession
)和二级缓存(可选配置,基于Mapper
映射器级别)。
2. MyBatis 的执行流程
MyBatis 的执行流程通常包括以下几个步骤:
2.1. 创建 SqlSessionFactory
-
MyBatis 的执行流程从加载配置文件并创建
SqlSessionFactory
开始。通过SqlSessionFactoryBuilder
读取 MyBatis 的配置文件(如mybatis-config.xml
)或通过代码配置,MyBatis 会构建Configuration
对象,解析所有 Mapper 文件,并将这些信息注册到Configuration
中。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2.2. 获取 SqlSession
-
通过
SqlSessionFactory
获取SqlSession
对象。SqlSession
是 MyBatis 与数据库交互的核心接口,所有的数据库操作都通过它来完成。
SqlSession sqlSession = sqlSessionFactory.openSession();
2.3. 执行 SQL 语句
-
通过
SqlSession
调用 Mapper 接口的方法,MyBatis 内部会将这些方法调用映射到相应的 SQL 语句上。
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
-
MyBatis 首先会通过
MappedStatement
获取相应的 SQL 语句,然后通过
Executor
执行 SQL。执行过程如下:
-
参数处理:
MappedStatement
中的 SQL 语句通常包含占位符(如#{id}
)。MyBatis 会根据传入的参数解析这些占位符,并生成实际的 SQL 语句。 -
SQL 执行:
Executor
会根据生成的 SQL 语句,通过 JDBC 与数据库交互,执行 SQL。 -
结果映射:
Executor
执行 SQL 后,返回的结果集会通过ResultSetHandler
映射为 Java 对象或集合。这一步是 MyBatis 自动将数据库结果集转换为应用程序中定义的 POJO。
-
2.4. 处理缓存
-
MyBatis 在执行 SQL 语句时,会首先检查缓存(一级缓存和二级缓存)中是否有结果。如果有,直接从缓存中获取结果;如果没有,则执行 SQL 并将结果缓存。
-
一级缓存:默认开启,作用于
SqlSession
级别。同一SqlSession
内的相同查询会直接从缓存中获取结果。 -
二级缓存:可选配置,作用于
Mapper
映射器级别。同一Mapper
内的相同查询会从二级缓存中获取结果。二级缓存需要在配置文件中显式启用。
-
2.5. 事务管理
-
MyBatis 的事务管理由
SqlSession
管理。SqlSession
提供了commit()
和rollback()
方法来提交或回滚事务。默认情况下,MyBatis 的事务是手动提交的,即需要开发者调用commit()
方法来提交事务。
try {
// 执行SQL操作
sqlSession.commit(); // 提交事务
} catch (Exception e) {
sqlSession.rollback(); // 回滚事务
throw e;
} finally {
sqlSession.close(); // 关闭会话
}
2.6. 关闭 SqlSession
-
每使用完
SqlSession
后,都应该关闭它,以释放数据库连接资源。
sqlSession.close();
3. 总结
-
配置阶段:MyBatis 通过
SqlSessionFactoryBuilder
读取配置文件并解析所有 Mapper 文件,构建SqlSessionFactory
。 -
会话阶段:通过
SqlSessionFactory
创建SqlSession
,在SqlSession
中执行 SQL 操作,并管理事务。 -
执行阶段:MyBatis 通过
MappedStatement
和Executor
处理 SQL 语句的执行,处理参数和结果映射,并利用缓存机制优化查询。 -
关闭会话:执行完操作后,关闭
SqlSession
以释放资源。
MyBatis 的执行原理体现了它作为一个半自动化持久层框架的设计理念,即通过 XML 配置或注解提供灵活的 SQL 操作控制,同时借助 MyBatis 的核心组件实现高效、简洁的数据库访问。