备注:本文修订于2022年6月29日。

1、MyBatis trim 标签

Mybatis具有实现动态SQL的能力,但是在拼凑SQL语句的时候,稍有不注意则会画蛇添足,此时可以通过 trim 标签来进行修剪。trim 是“修剪”的意思,其基本格式如下:

<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>

trim 标签的主要属性有四个,如下表所示:

属性名 作用
prefix 给sql增加前缀
suffix 给sql增加后缀
prefixOverrides 去掉sql前面多余的关键字或者字符
suffixOverrides 去掉sql后面多余的关键字或者字符

2、prefix 使用场景介绍

<select id="getUser" resultType="user">
 select * from t_users 
 <trim prefix="where">
  name = #{name} and age = #{age} and phone = #{phone}
 </trim>
</select>

在动态生成SQL的过程中,会将prefix前缀拼接到trim标签的外侧,最终得到的SQL如下:

select * from t_users where name= ? and age= ? and phone = ?

3、prefixOverrides 使用场景介绍

<select id="getUser" resultType="user">
 select * from t_users 
 <trim prefix="where">
  <if test="name != null">
   name=#{name}
  </if>
  <if test="age != null">
   and age=#{age}
  </if>
  <if test="phone != null">
   and phone=#{phone}
  </if>
 </trim>
</select>

在动态 SQL 的拼接过程中,如果 name 为 null,则第一个 if 不成立,里面的 SQL 语句不拼接,第二个 if 里面的 and 会紧跟在 where 后面,造成语法错误,最终动态生成的 SQL 如下:

select * from t_users where and age = ? and phone = ?

为了解决这个问题,只要加上 prefixOverrides 即可:

<select id="getUser" resultType="user">
 select * from t_users 
 <trim prefix="where" prefixOverrides="and">
  <if test="name != null">
   name=#{name}
  </if>
  <if test="age != null">
   and age=#{age}
  </if>
  <if test="phone != null">
   and phone=#{phone}
  </if>
 </trim>
</select>

当然,prefix 和 prefixOverrides 可以放在一起综合使用,如下所示:

select * from t_users 
<trim prefix="WHERE" prefixOverrides="AND|OR">
  <if test="name != null and name.length() > 0"> AND name=#{name}</if>
  <if test="gender != null and gender.length() > 0"> AND gender=#{gender}</if>
</trim>

假如name和gender的值都不为null,打印出的SQL是这样的:

select * from t_users where  name = ? and gender = ?

where后不存在and,这是因为prefixOverrides="AND|OR"代表去掉第一个and或者是or。

4、suffix 和 suffixOverrides 使用场景介绍

update t_users 
<trim prefix="set" suffixOverrides="," suffix=" where id = #{id} ">
  <if test="name != null and name.length() > 0"> name=#{name}, </if>
  <if test="gender != null and gender.length() > 0"> gender=#{gender},  </if>
</trim>

假如name和gender的值都不为null,打印出的SQL为:

update t_users set name = ? , gender = ?  where id = ?

trim 标签的作用是:在 gender = ? 后面裁剪了逗号,而且自动加了一个 set 前缀和 where 后缀。

5、提醒

prefix 是给整个字符串增加一个前缀,而 prefixOverrides 则是去掉整个字符串前面多余的字符。
suffix 是给整个字符串增加一个后缀,而 suffixOverrides 则是去掉整个字符串后面多余的字符。

其实,上述的处理过程与 set 标签类似,针对的都是整个字符串后面的多余字符。

标签: none

添加新评论