MyBatis 的动态 SQL 功能允许我们在 XML 映射文件中,编写可以根据不同条件动态变化的 SQL 语句,这极大地避免了在 Java 代码中拼接 SQL 字符串的麻烦和潜在风险(如 SQL 注入)。
下面是其中常用的几个标签🏷
1. <where> 标签
- 功能:专门用于处理 WHERE 子句的动态条件。
- 痛点解决:我们经常需要根据条件拼接 WHERE 后的 AND/OR,手动处理第一个或最后一个多余的 AND 非常麻烦且容易出错。
智能之处:
- 只有当标签内至少有一个条件成立时,它才会自动插入 WHERE 关键字。
- 它会自动去除紧跟在 WHERE 后面多余的 AND 或 OR,你无需担心条件开头有多余的连接词。
示例:
<select id="findUser" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
- 如果 name 和 email 都为 null,生成的 SQL 是:SELECT * FROM users
- 如果只有 name 不为 null,生成的 SQL 是:SELECT * FROM users WHERE name = ? (它智能地去掉了开头的 AND)
2. <foreach> 标签
- 功能:遍历一个集合(如 List、Set、数组或 Map),并对集合中的每一项进行迭代,通常用于构建 IN 条件语句或批量操作。
常见属性:
- collection:指定要遍历的集合参数,名称要与接口方法传入的参数名一致。
- item:在迭代过程中,每个元素的别名。
- index:在列表或数组中,index 是当前迭代的序号;在 Map 中,index 是键(key)。
- open:整个循环内容开始时的字符串(如 "(")。
- close:整个循环内容结束时的字符串(如 ")")。
- separator:每次迭代之间的分隔符(如 ",")。
- 经典场景:根据一组 ID 查询用户
示例:
<select id="findUsersByIds" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach collection="idList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
- 假设传入的 idList 是 [1,2,3],生成的 SQL 为:SELECT * FROM users WHERE id IN (1,2,3)
另一个场景:批量插入
<insert id="insertUsers">
INSERT INTO users (name, email) VALUES
<foreach collection="userList" item="user" separator=",">
(#{user.name}, #{user.email})
</foreach>
</insert>
3. <sql> 和 <include> 标签
这是一对组合标签,用于代码复用。
<sql> 标签:
- 功能:定义一段可重用的 SQL 代码片段。
- 用途:将常见的列列表、表名或复杂的 WHERE 子句封装起来,避免重复编写(遵守 DRY - Don‘t Repeat Yourself 原则)。
<include> 标签:
- 功能:引用一个已被 <sql> 定义好的代码片段。
- 属性:refid,指定要引用的 <sql> 片段的 id。
示例:
<!-- 1. 先定义公共的列列表 -->
<sql id="userColumns">
id, name, email, create_time
</sql>
<select id="selectAllUsers" resultType="User">
SELECT
<include refid="userColumns"/>
<!-- 2. 在这里引用 -->
FROM users
</select>
<select id="selectUserById" resultType="User">
SELECT
<include refid="userColumns"/>
<!-- 重复使用 -->
FROM users
WHERE id = #{id}
</select>
总结
1. <where> 标签
· 核心作用:用于动态生成 SQL 语句中的 WHERE 子句。
· 主要优点:具有智能处理能力。它能自动判断其内部包含的条件语句,仅在至少有一个条件成立时,才会向SQL中插入 WHERE 关键字。更重要的是,它会自动去除紧随在 WHERE 之后多余的 AND 或 OR 连接词,从而避免了因条件动态变化而导致的语法错误,开发者无需手动处理这些情况。
2. <foreach> 标签
· 核心作用:用于遍历(循环)一个集合或数组,并对集合中的每一项进行迭代,生成对应的SQL片段。
· 主要优点:极大地简化了需要对集合进行循环操作的SQL编写。它完美解决了诸如 IN (item1, item2, ...) 查询和批量插入(INSERT INTO ... VALUES (...), (...), ...)等需要动态拼接大量参数的场景,避免了在Java代码中进行繁琐且易错的字符串拼接。
3. <sql> 标签
· 核心作用:用于定义一段可重用的 SQL 代码片段,起到代码复用的目的。
· 主要优点:遵循 DRY(Don't Repeat Yourself)原则。可以将常见的列名列表、复杂的条件判断等公共部分抽取出来,统一维护和管理。当需要修改时,只需修改一处定义,所有引用的地方都会生效,大大提高了代码的可维护性和整洁性。
4. <include> 标签
· 核心作用:用于引用一个由 <sql> 标签定义好的可重用 SQL 片段。
· 主要优点:与 <sql> 标签配合使用,实现了SQL片段的“一次定义,多处引用”。通过在需要的地方简单地引用片段的ID,就可以将公共SQL部分包含进来,使得映射文件更加简洁和模块化。
如有错误,敬请指出🙏🏻
1592

被折叠的 条评论
为什么被折叠?



