在 MyBatis 中,MappedStatement
是一个核心类,它表示一个映射语句的配置项,用于将 SQL 查询、更新、插入等操作与 Mapper
接口方法进行关联。MappedStatement
是 MyBatis 中 SQL 执行的配置和管理的核心对象之一。它保存了 SQL 语句的元数据、参数类型、返回值类型等信息。
1. MappedStatement
的作用和概述
在 MyBatis 中,每个 SQL 映射语句(如 select
, insert
, update
, delete
)都会生成一个 MappedStatement
实例。它充当着 SQL 执行的配置对象,将一个 SQL 语句的描述与 Mapper
方法的调用过程联系起来。MappedStatement
作为 MyBatis 中最重要的执行元数据之一,存储了与 SQL 执行相关的所有信息。
2. MappedStatement
的构成
一个 MappedStatement
对象通常包含以下几个重要的组成部分:
- ID:映射语句的唯一标识符,对应
Mapper
文件中 SQL 映射的id
属性。 - SQL 语句:具体的 SQL 查询语句,可能是
select
、insert
、update
或delete
。 - 参数类型:方法参数的类型,通常是一个 POJO 类或者基本类型,用于绑定查询条件或插入数据。
- 返回类型:执行 SQL 后返回的数据类型,通常是一个 Java 类或集合类型。
- SQL 执行类型:表示该 SQL 是查询、更新、插入还是删除操作。
- 缓存配置:与二级缓存相关的配置,
MappedStatement
中包含了关于缓存的设置。 - 结果映射:指定如何将 SQL 查询结果映射成 Java 对象,通常是通过
resultMap
来配置。 - 执行器:
MappedStatement
会被Executor
使用,Executor
负责执行实际的 SQL 操作。
3. MappedStatement
的生命周期
MappedStatement
是 MyBatis 映射文件解析后得到的对象。在 MyBatis 启动时,SqlSessionFactory
会加载所有的 Mapper
配置文件,并解析其中的 SQL 映射语句(即 select
, insert
, update
, delete
)。每解析一个 SQL 映射语句,就会生成一个 MappedStatement
对象并将其保存在 Configuration
的 mappedStatements
中。
MappedStatement
存储了 SQL 的所有相关元数据(例如:SQL 语句、返回类型、参数类型、查询映射、缓存等信息)。SqlSession
在执行 SQL 时会通过MappedStatement
获取这些元数据,并执行相关的 SQL 操作。
4. MappedStatement
的创建
在 MyBatis 启动时,MyBatis 会解析配置文件中的 Mapper
文件,并将其中的 SQL 映射信息转化为 MappedStatement
对象。每个 Mapper
文件的 select
、insert
、update
、delete
标签对应一个 MappedStatement
。例如,<select id="selectUserById" ...>
标签对应一个 MappedStatement
。
示例:解析过程
假设有一个 Mapper
接口和 XML 映射文件如下:
UserMapper.java
:
public interface UserMapper {
User selectUserById(int id);
}
UserMapper.xml
:
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" resultType="com.example.model.User" parameterType="int">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
在 MyBatis 启动时,UserMapper.xml
会被解析,<select>
标签会被转换为一个 MappedStatement
对象。
MappedStatement mappedStatement = new MappedStatement.Builder(configuration, "selectUserById", sqlSource, SqlCommandType.SELECT)
.parameterMap(parameterMap)
.resultMap(resultMap)
.build();
sqlSource
:存储 SQL 查询语句和参数的SqlSource
对象。parameterMap
:映射 SQL 参数和方法参数之间的关系。resultMap
:映射 SQL 查询结果和 Java 对象之间的关系。
MappedStatement
被 Configuration
对象存储在 mappedStatements
中,SqlSession
执行时会根据 id
获取对应的 MappedStatement
,并执行 SQL。
5. MappedStatement
的字段说明
以下是 MappedStatement
类的一些重要字段及其含义:
- id:映射语句的唯一标识符。通常是
Mapper
接口方法的名称,或映射文件中 SQL 语句的id
属性。 - sqlSource:SQL 源,它包含了 SQL 语句及其相关信息。
SqlSource
接口的实现类有RawSqlSource
、StaticSqlSource
和DynamicSqlSource
等。 - parameterMap:参数映射,表示 SQL 语句中的参数如何与方法参数进行映射。
- resultMap:结果映射,定义如何将 SQL 查询结果映射成 Java 对象。
- sqlCommandType:SQL 执行类型,表示 SQL 是
select
、insert
、update
还是delete
。 - fetchSize:SQL 执行时的
fetchSize
,用于设置一次从数据库中获取的记录数。 - timeout:SQL 执行的超时时间,单位为秒。
- cache:是否启用缓存。可以为
true
或false
。 - flushCacheRequired:是否要求在执行 SQL 时刷新缓存。
- useCache:是否使用缓存。
6. MappedStatement
和 Executor
的关系
当 MyBatis 执行 SQL 时,它会通过 MappedStatement
来获取 SQL 语句的相关信息,然后交给 Executor
来执行。Executor
会根据 SQL 类型(查询、更新等)来选择合适的执行方式。
例如,执行查询时,Executor
会通过 MappedStatement
获取 SqlSource
和 parameterMap
,然后执行 SQL,并将结果映射成 Java 对象。Executor
还会根据是否开启了缓存来决定是否将查询结果缓存。
7. 总结
MappedStatement
是 MyBatis 中用于存储 SQL 映射的核心对象,包含了 SQL 语句、参数类型、返回类型等元数据。- 它是 MyBatis 在执行 SQL 时查询数据库、映射结果、管理缓存等操作的基础。
- 每个 SQL 映射语句(如
select
、insert
、update
、delete
)都会生成一个MappedStatement
,并通过Executor
执行。 MappedStatement
可以配置缓存、结果映射、参数映射等信息,是 MyBatis 中执行 SQL 操作的关键。