Mybatis 动态 SQL - trim, where, set

之前的例子都巧妙地避开了一个臭名昭著的动态SQL挑战。考虑一下如果我们回到之前的“if”例子,但这次我们将“ACTIVE = 1”也作为一个动态条件。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

如果没有满足任何条件,会发生什么?你最终会得到类似于下面的SQL语句:

SELECT * FROM BLOG
WHERE

如果只有第二个条件满足,最终的SQL语句将如下所示:

SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’

这也会失败。这个问题不容易通过条件语句解决,如果你曾经不得不写过它,那么你很可能再也不想这样做了。

MyBatis 在大多数情况下有一个简单的答案,可能在 90% 的情况下都能起作用。而在它无法满足要求的情况下,你可以自定义它来达到目的。只需要一个简单的改变,一切都会正常工作:

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

如果 ​<where>​元素中的嵌套标签返回任何内容,它会知道只在查询条件非空时插入 "WHERE" 关键字。此外,如果条件的内容以 "AND" 或 "OR" 开头,它会自动去掉这些关键字。

如果`<where>`元素的行为不符合您的要求,您可以通过定义自己的`<trim>`元素来进行自定义。例如,与`<where>`元素相对应的`<trim>`元素可以是:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

​<trim>​元素的 ​prefixOverrides​属性接受一个使用管道符分隔的文本列表,其中空格是有关的。结果是删除 ​prefixOverrides​属性中指定的内容,并插入 ​prefix​属性中指定的内容。

对于动态更新语句,也有一个类似的解决方案,称为`<set>`元素。`<set>`元素可以用于动态包含要更新的列,以及排除其他列。例如:

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

在这个例子中,​<set>​元素将动态添加 "SET" 关键字,并且在应用条件后消除任何多余的逗号。

另外,您也可以通过使用`<trim>`元素来实现相同的效果:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

请注意,在这种情况下,我们覆盖的是后缀,而仍然附加前缀。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值