深入浅出MyBatis:动态SQL语句
浅析MyBatis:动态SQL总结
动态SQL是MyBatis的强大特性之一。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
| 元素 | 作用 | 备注 |
|---|---|---|
| if | 判断语句 | 单条件分支判断 |
| choose(when、otherwise) | 判断语句 | 多分支条件判断 |
| trim、where、set | 辅助元素 | 用于处理一些SQL拼装问题 |
| foreach | 循环语句 | 在In语句等列举条件常用 |
| bind | 辅助元素 | 拼接系数 |
if
根据条件判断是否包含某段SQL
<select id="findUser">
SELECT * FROM users
<if test="name != null"> name = #{name}</if>
</select>
test对应的是判断条件,if标签之间的SQL语句在条件满足的时候拼接到SQL语句中
choose(when、otherwise)
类似编程中的switch-case逻辑
<choose>
<when test="role == 'admin'">AND access_level > 90</when>
<when test="role == 'user'">AND access_level < 90 </when>
<otherwise>AND access_level IS NOT NULL</otherwise>
</choose>
choose标签常常和when标签以及otherwise标签一起使用
choose标签可以看作是多分支结构的一个开关,when标签是多分支结构上的分支,条件满足的时候会将内含的SQL拼接到前面的SQL语句上,otherwise标签是多分支结构上的默认分支,所有的when标签含有的条件不满足的时候会将otherwise标签内含的SQL语句拼接上
where、trim、set
自动处理多余的AND、OR或逗号
where
<where> 关键字只会去掉库表字段赋值前面的AND或OR,不会去掉语句后面的AND关键字
用于拼接WHERE子句,自动处理WHERE关键字和添加适当的AND或OR连接条件。
<select id="findUser">
SELECT * FROM users
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
set
用于拼接UPDATE语句的SET子句,自动处理SET关键字和添加适当的逗号分隔更新字段
<update id="updateSelectiveUser">
UPDATE tb_user
<set>
<if test="userName != null and userName.trim() != ''">
user_name = #{userName},
</if>
<if test="address != null and address.trim() != ''">
address = #{address},
</if>
</set>
WHERE id = #{id}
</update>
案例中的每个if标签包含的SQL语句末尾都含有
,结尾,有了set标签后可以保证在运行该语句的时候把,结尾根据适配,即最后一个条件满足的时候不会保留,结尾
trim
用于去除或补齐SQL语句片段的开头和结尾的空格,可以用于拼接包含可选条件的SQL语句。
<select id="findUser">
SELECT * FROM users
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="name != null">AND name = #{name}</if>
<if test="age != null">OR age = #{age}</if>
</trim>
</select>
prefixOverrides="AND |OR ":自动去除开头的AND或OR。
trim标签有四个属性:prefix、suffix、prefixOverrides和suffixOverrides。
prefix和suffix用于添加前后缀,prefixOverrides和suffixOverrides用于去除多余的部分。例如,在更新语句中,每个字段后面可能有一个逗号,最后一个字段的逗号需要去掉。这时候可以设置suffixOverrides为逗号,这样trim标签会自动处理。
foreach
用于循环遍历集合或数组,并在SQL语句中插入对应的元素作为参数。可以指定开始位置、结束位置、分隔符等属性.
oreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。
可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
bind
bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。
场景1:模糊查询(自动拼接 %)
假设需要根据用户输入的关键词进行模糊查询(如 LIKE %keyword%)。
使用 <bind> 可以避免手动拼接 %,并确保参数格式统一。
Mapper XML示例:
<select id="searchUsers" resultType="User">
<!-- 将 keyword 转换为前后带通配符的 searchPattern -->
<bind name="searchPattern" value="'%' + keyword + '%'" />
SELECT * FROM users
WHERE
username LIKE #{searchPattern}
OR email LIKE #{searchPattern}
</select>
调用代码:
List<User> users = userMapper.searchUsers("john");
// 实际SQL:SELECT * FROM users WHERE username LIKE '%john%' OR email LIKE '%john%'
场景2:动态排序字段
根据前端传入的排序字段和方向(如 sortField=age&sortOrder=DESC),动态生成 ORDER BY 子句。
Mapper XML示例:
<select id="getUsers" resultType="User">
<!-- 拼接排序字段和方向 -->
<bind name="orderByClause"
value="sortField + ' ' + (sortOrder == 'DESC' ? 'DESC' : 'ASC')" />
SELECT * FROM users
<if test="sortField != null and sortOrder != null">
ORDER BY ${orderByClause}
</if>
</select>
调用代码:
List<User> users = userMapper.getUsers("age", "DESC");
// 实际SQL:SELECT * FROM users ORDER BY age DESC
本文来自博客园,作者:Eulbo_1018,转载请注明原文链接:https://www.cnblogs.com/eulbo-1018/p/18818022

浙公网安备 33010602011771号