MyBatis XML映射文件通过<resultMap>处理复杂结果映射,用<association>和<collection>支持一对一、一对多嵌套;借助<if>、<where>、<foreach>等动态SQL标签构建安全灵活查询;利用<sql>与<include>复用SQL片段;参数用#{}预编译防注入,批量操作依赖<foreach>。

MyBatis 的 XML 映射文件是处理复杂 SQL 查询的核心方式,尤其适合动态条件、多表关联、嵌套结果等场景。关键在于合理使用 <select> 标签配合动态 SQL 元素(如 <if>、<choose>、<foreach>、<resultMap>)和 SQL 片段复用。
定义 resultMap 处理复杂结果映射
当查询涉及多表关联、字段名与属性名不一致、或存在嵌套对象/集合时,不能依赖自动映射,需显式定义 <resultMap>。
- 用
id属性唯一标识 resultMap,type指定返回的 Java 类型 - 用
<id>映射主键字段(提升性能),<result>映射普通字段 - 用
<association>映射一对一关系(如订单 → 用户),支持嵌套select或嵌套resultMap - 用
<collection>映射一对多关系(如用户 → 订单列表),同样支持嵌套查询或嵌套 resultMap
示例:查用户及其所有订单(一对多)
<resultMap id="UserWithOrdersResultMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <collection property="orders" ofType="Order" resultMap="OrderResultMap"/> </resultMap> <p><resultMap id="OrderResultMap" type="Order"> <id property="id" column="order_id"/> <result property="amount" column="order_amount"/> </resultMap>
用动态 SQL 构建灵活查询条件
避免拼接字符串,用 MyBatis 提供的标签实现安全、可读的条件组装。
立即学习“Java免费学习笔记(深入)”;
-
<where>自动处理 WHERE 关键字和首条件前的 AND/OR —— 推荐替代手写WHERE 1=1 -
<if test="xxx != null and xxx != ''">判断单个参数是否满足条件 -
<choose><when test="..."/><otherwise>实现类似 switch-case 的多分支逻辑 -
<foreach collection="list" item="item" open="(" separator="," close=")">遍历集合生成 IN 语句
示例:根据用户名、状态、创建时间范围动态查询
<select id="findUsers" resultMap="UserResultMap">
SELECT * FROM user u
<where>
<if test="username != null and username != ''">
u.username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="status != null">
AND u.status = #{status}
</if>
<if test="startTime != null">
AND u.create_time >= #{startTime}
</if>
<if test="endTime != null">
AND u.create_time <= #{endTime}
</if>
</where>
ORDER BY u.create_time DESC
</select>复用 SQL 片段减少重复
用 <sql> 定义可重用的 SQL 片段(如常用字段、JOIN 子句),再通过 <include> 引入。
- 片段中可用
<bind>创建新变量,例如格式化模糊查询值 - 支持传参:在
<include>中用<property>传递别名或表前缀
示例:
<sql id="userColumns">
u.id AS user_id,
u.username AS user_name,
u.email AS user_email
</sql>
<p><select id="getUserById" resultType="map">
SELECT <include refid="userColumns"/>
FROM user u
WHERE u.id = #{id}
</select>执行带参数的复杂查询(含分页、批量操作)
XML 中可通过 #{} 绑定参数(预编译,防注入),${} 仅作字符串替换(慎用,如动态表名)。
- 分页建议交由插件(如 PageHelper)处理,XML 写基础查询即可
- 批量插入用
<foreach>生成多值 INSERT(注意数据库限制) - 批量更新/删除同理,用
IN或foreach构造条件
示例:批量插入订单
<insert id="batchInsertOrders">
INSERT INTO order (user_id, amount, create_time)
VALUES
<foreach collection="orders" item="order" separator=",">
(#{order.userId}, #{order.amount}, #{order.createTime})
</foreach>
</insert>


















