Mybatis之动态SQL

动态SQL标签

  • IF标签 choose、
  • when标签
  • otherwise标签
  • where标签
  • set标签
  • foreach标签

SQL片段

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

Mybatis之动态SQL_第1张图片

IF标签

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:

 <if test="title != null">  </if>    test为表达式
   SELECT * FROM   BLOG  WHERE state = ‘ACTIVE’ 如果if里的title != null 那么久追加一句SQL语句:title like #{title}

变成: SELECT * FROM BLOG WHERE state = ‘ACTIVE’ AND title like #{title}

<select id="findActiveBlogWithTitleLike"  resultType="Blog">
    SELECT * FROM BLOG
      WHERE state = ‘ACTIVE’
    <if test="title != null">
    AND title like #{title}
     </if>
</select>

choose、when、otherwise标签

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。但是如果写成上面的那么多个IF标签不太合理。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。

若两者都没有传入,就拼接标记的 SQL。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

但是where语句有个弊端,如果where后面直接跟或者但是条件都没有满足的话会出现where后面直接跟and的错误,例如下面:
在这里插入图片描述

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG  WHERE    //后面直接跟if标签了没有了在一个条件缓冲
  <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>

结果成这样:

SELECT * FROM BLOG  WHERE  AND title like ‘someTitle’

where标签

为了解决上述问题,进行小小变动,把where写成一个标签
并且where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<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>

set标签

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>

foreach标签

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:
集合项(item)和索引(index)变量以及返回对象类型collection

<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>

Mybatis之动态SQL_第2张图片

SQL片段

用于一些代码总是复写时,可以抽取出来成为公共的,用时直接使用include标签引用

Mybatis之动态SQL_第3张图片

你可能感兴趣的:(mybatis,sql,java)