如果这些条件没有一个能匹配上会发生什么?最终这条 SQL 会变成这样:

    1. SELECT * FROM BLOG
    2. WHERE

    这会导致查询失败。如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样:

    这个查询也会失败。这个问题不能简单地用条件句式来解决,如果你也曾经被迫这样写过,那么你很可能从此以后都不会再写出这种语句了。

    1. <select id="findActiveBlogLike"
    2. resultType="Blog">
    3. SELECT * FROM BLOG
    4. <where>
    5. <if test="state != null">
    6. state = #{state}
    7. <if test="title != null">
    8. AND title like #{title}
    9. </if>
    10. <if test="author != null and author.name != null">
    11. AND author_name like #{author.name}
    12. </if>
    13. </where>
    14. </select>

    where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

    如果 where 元素没有按正常套路出牌,我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

    prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。它的作用是移除所有指定在 prefixOverrides 属性中的内容,并且插入 prefix 属性中指定的内容。

    1. update Author
    2. <set>
    3. <if test="username != null">username=#{username},</if>
    4. <if test="password != null">password=#{password},</if>
    5. <if test="email != null">email=#{email},</if>
    6. <if test="bio != null">bio=#{bio}</if>
    7. </set>
    8. where id=#{id}

    这里,set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。(译者注:因为用的是“if”元素,若最后一个“if”没有匹配上而前面的匹配上,SQL 语句的最后就会有一个逗号遗留)

    若你对 set 元素等价的自定义 trim 元素的代码感兴趣,那这就是它的真面目:

    注意这里我们删去的是后缀值,同时添加了前缀值。