where、set、trim用法
这 3 个标签解决了类似的问题,并且 where 和 set 都属于 trim 的一种具体用法。下面分别来看这 3 个标签。
where用法
where 标签的作用:如果该标签包含的元素中有返回值,就插入一个 where;如果 where 后面的字符串是以 AND 和 OR 开头的,就将它们剔除。
首先修改 UserMapper.xml 中的 selectByUser 方法,注意这个方法在4.1.1节中的用法。此处将这个方法改成使用 where 标签,代码如下。
<select id="selectByUser" resultType="tk.mybatis.simple.model.SysUser">
select id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userInfo,
head_img headImg,
create_time createTime
from sys_user
<where>
<if test="userName != null and userName != ''">
and user_name like concat('%',#{userName},"%")
</if>
<if test="userEmail != null and userEmail != ''">
and user_email = #{userEmail}
</if>
</where>
</select>
当 if 条件都不满足的时候,where 元素中没有内容,所以在 SQL 中不会出现 where,也就不存在4.1.1节中 SQL 错误的问题。如果 if 条件满足,where 元素的内容就是以 and 开头的条件,where 会自动去掉开头的 and,这也能保证 where 条件正确。和4.1.1节中相比,这种情况下生成的 SQL 更干净、更贴切,不会在任何情况下都有 where 1=1 这样的条件。
set用法
set 标签的作用:如果该标签包含的元素中有返回值,就插入一个 set;如果 set 后面的字符串是以逗号结尾的,就将这个逗号剔除。
修改 UserMapper.xml 中的 updateByIdSelective 方法,注意和4.1.2节中的区别,代码如下。
<update id="updateByIdSelective">
update sys_user
<set>
<if test="userName != null and userName != ''">
user_name = #{userName},
</if>
<if test="userPassword != null and userPassword != ''">
user_password = #{userPassword},
</if>
<if test="userEmail != null and userEmail != ''">
user_email = #{userEmail},
</if>
<if test="userInfo != null and userInfo != ''">
user_info = #{userInfo},
</if>
<if test="headImg != null">
head_img = #{headImg,jdbcType=BLOB},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
id = #{id},
</set>
where id = #{id}
</update>
在 set 标签的用法中,SQL 后面的逗号没有问题了,但是如果 set 元素中没有内容,照样会出现 SQL 错误,所以为了避免错误产生,类似 id=#{id}
这样必然存在的赋值仍然有保留的必要。从这一点来看,set 标签并没有解决全部的问题,使用时仍然需要注意。
trim用法
where 和 set 标签的功能都可以用 trim 标签来实现,并且在底层就是通过 TrimSqlNode 实现的。
where 标签对应 trim 的实现如下。
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
这里的 AND 和 OR 后面的空格不能省略,为了避免匹配到 andes、orders 等单词。 |
实际的 prefixeOverrides 包含 “AND”、“OR”、“AND\n”、“OR\n”、“AND\r”、“OR\r”、“AND\t”、“OR\t”,不仅仅是上面提到的两个带空格的前缀。
set 标签对应的 trim 实现如下。
<trim prefix="SET" suffixOverrides=",">
...
</trim>
trim 标签有如下属性。
-
prefix:当 trim 元素内包含内容时,会给内容增加 prefix 指定的前缀。
-
prefixOverrides:当 trim 元素内包含内容时,会把内容中匹配的前缀字符串去掉。
-
suffix:当 trim 元素内包含内容时,会给内容增加 suffix 指定的后缀。
-
suffixOverrides:当 trim 元素内包含内容时,会把内容中匹配的后缀字符串去掉。