Mybatis作为常用的ORM框架,核心能力之一就是通过XML映射文件将Java方法和SQL语句进行绑定,让开发人员无需手动编写JDBC的冗余代码就能完成数据库操作。XML映射文件的工作流程贯穿Mybatis的初始化和运行两个阶段,每个阶段都有明确的逻辑分工。

XML映射文件的初始化加载阶段
Mybatis启动时首先会读取配置文件,其中会指定XML映射文件的扫描路径。框架会遍历指定路径下的所有XML文件,对每个符合规范的映射文件进行解析。
解析过程首先会校验XML文件的格式是否符合Mybatis的DTD约束,之后会提取文件中的根标签<mapper>的namespace属性,这个属性需要和对应的Mapper接口的全限定名保持一致,用来建立映射文件和接口的一一对应关系。
接下来会解析根标签下的各类子标签,包括<select>、<insert>、<update>、<delete>等SQL定义标签,以及<resultMap>、<parameterMap>等配置标签。每个SQL标签会被解析为一个MappedStatement对象,这个对象包含了SQL语句、参数映射规则、结果映射规则等所有执行需要的信息,最终会被存储到Configuration全局配置对象的mappedStatements集合中,key是namespace加上SQL标签的id组成的唯一标识。
XML映射文件的运行执行阶段
当业务代码调用Mapper接口的方法时,Mybatis会通过动态代理生成Mapper接口的代理对象,代理对象会根据调用的方法名和参数,拼接出对应的MappedStatement的key,从Configuration中获取到对应的MappedStatement对象。
之后会进入SQL处理流程,首先会对SQL中的参数占位符进行处理,将传入的Java参数按照<parameterMap>或者参数注解的规则转换为JDBC对应的参数类型,如果XML中使用了动态SQL标签,比如<if>、<foreach>等,还会在这个阶段根据参数值动态拼接最终的SQL语句。
处理完成的SQL会交给底层的Executor执行器,执行器会调用JDBC的PreparedStatement执行SQL,之后会根据MappedStatement中配置的结果映射规则,将数据库返回的结果集转换为Java对象,最终返回给调用方。
XML映射文件核心标签示例
下面是一个典型的XML映射文件示例,展示了基础的SQL定义和动态SQL的使用方式:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://ipipp.com/dtd/mybatis-3-mapper.dtd">
<!-- namespace对应Mapper接口的全限定名 -->
<mapper namespace="com.example.mapper.UserMapper">
<!-- 定义结果映射,将数据库字段和Java对象属性对应 -->
<resultMap id="userResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<result column="age" property="age"/>
</resultMap>
<!-- 基础查询语句,使用resultMap映射结果 -->
<select id="selectById" resultMap="userResultMap">
SELECT id, user_name, age FROM user WHERE id = #{id}
</select>
<!-- 动态SQL示例,根据参数条件拼接查询条件 -->
<select id="selectByCondition" resultMap="userResultMap">
SELECT id, user_name, age FROM user
<where>
<if test="userName != null and userName != ''">
AND user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
<!-- 插入语句示例 -->
<insert id="insertUser" parameterType="com.example.entity.User">
INSERT INTO user (user_name, age) VALUES (#{userName}, #{age})
</insert>
</mapper>
常见问题说明
很多开发人员会遇到XML映射文件中的SQL不生效的问题,通常可以从以下几个方向排查:
- 检查<mapper>标签的namespace是否和Mapper接口的全限定名完全一致
- 检查SQL标签的id是否和Mapper接口的方法名一致
- 检查Mybatis配置文件中是否正确配置了XML映射文件的扫描路径
- 检查动态SQL的test表达式是否符合OGNL语法规则
理解XML映射文件的工作流程,不仅能帮助我们快速排查使用过程中的问题,也能让我们更合理地设计映射文件的结构,提升数据库操作的开发效率。