引言
在我们上一篇文章,完成了反射工具类,在这篇文章,我们要实现对xml文件中SQL的解析。
实现目标
在XMLConfigBuilder中完成对SQL的解析。
在我们之间,已经把环境解析完成了,我们这回就在这里完成SQL解析。
// 环境
environmentsElement(root.element("environments"));
流程图
解析标签
在XMLConfigBuilder中创建mapperElement方法,我们在这里解析所有的mapper标签
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
<mappers>
每一个mapper标签都会被XMLMapperBuilder.parse方法解析。
<mapper namespace="com.example.mapper.UserMapper">
<!-- 字段映射配置(当数据库字段与Java属性不一致时使用) -->
<resultMap id="userResultMap" type="com.example.entity.User">
<id property="id" column="user_id" /> <!-- 主键映射 -->
<result property="username" column="user_name" /> <!-- 普通字段映射 -->
<result property="email" column="user_email" />
<result property="createTime" column="create_time" /> <!-- 驼峰命名自动映射可不配置 -->
</resultMap>
<!-- 示例1:基础查询(带条件) -->
<select id="selectUserById" resultMap="userResultMap">
SELECT user_id, user_name, user_email, create_time
FROM users
WHERE user_id = #{userId}
</select>
</mapper>
正常我们会先解析 cacheElement, resultMapElements,buildStatementFromContext
我们这里就先实现buildStatementFromContext。
XMLStatementBuilder
在这里我们就要使用上面这个构建了。
在这里我们就会开始解析出一个SQL。
解析SQL标签
问题来了,我们在这里都会解析些什么呢?
1. 解析 SQL 标签的基本属性
2. 解析 SQL 内容与动态标签
动态 SQL 处理:解析
<if>
,<where>
,<foreach>
,<trim>
等标签,生成SqlSource
对象。xml
<select id="findUser">
SELECT * FROM user
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
3. 主键生成策略
示例:
xml
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id" keyColumn="user_id">
INSERT INTO users (name) VALUES (#{name})
</insert>
4. 参数映射(ParameterMap)
过时配置:MyBatis 3 已废弃
<parameterMap>
,推荐内联参数映射。内联参数处理:通过
#{property}
自动映射参数,可指定jdbcType
或typeHandler
。xml
<select id="selectUser" resultType="User">
SELECT * FROM user WHERE id = #{id, jdbcType=BIGINT, typeHandler=MyTypeHandler}
</select>
5. 结果映射(ResultMap)
引用外部
<resultMap>
:通过resultMap
属性指定已定义的映射规则。自动映射:若未指定
resultMap
或resultType
,MyBatis 尝试通过列名与属性名自动映射。
6. 缓存相关配置
7. 其他高级配置
8. 解析流程总结
读取基础属性:从 SQL 标签中提取
id
,parameterType
,resultType
等属性。处理动态 SQL:通过
XMLScriptBuilder
解析动态标签,生成SqlSource
。主键策略配置:解析
useGeneratedKeys
,keyProperty
,keyColumn
。缓存配置:设置
flushCache
和useCache
。构建 MappedStatement:将解析结果封装为
MappedStatement
并注册到Configuration
。
最后 这些内容都会组装成一个mapperStatement,存在configuration之中。
生成SqlSource
获取默认语言驱动器并解析SQL的操作。其实这部分就是 XML 脚步语言驱动器所实现的功能,在 XMLScriptBuilder 中处理静态SQL和动态SQL。
定义脚本语言驱动接口,提供创建 SQL 信息的方法,入参包括了配置、元素、参数。其实它的实现类一共有3个;XMLLanguageDriver
、RawLanguageDriver
、VelocityLanguageDriver
,这里我们只是实现了默认的第一个即可。
大家可以参考这里的流程图,这个是总流程图的部分。