MyBatis的动态SQL

动态SQL

动态SQL是MyBatis的强大特性之一。在MyBatis中需要借助OGNL的表达式。

  • if
  • choose(when,otherwise)
  • trim(where set)
  • foreach

if

if:判断语句

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

当title不为空时,执行后面的查询语句。否则相反。

choose、when、otherwise

当我们不想使用所有的条件,而只想从多个条件选择使用一个。可以使用choose元素,类似Java中的switch语句。

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

trim、where、set

例子:

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

这时候我们可以使用where元素,它会将子句开头的 “AND” 或 “OR”除去。

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

我们还可以使用trim自定义:

  • trim:自定义字符串的截取规则
  • prefix="":前缀,trim标签体中是整个字符串拼串后的结果。prefix给拼串后的整个字符串加一个前缀。
  • prefixOverrides="":前缀覆盖,去掉整个字符串前面多余的字符串。
  • suffix="":后缀,suffix给拼串后的结果加一个后缀
  • suffixOverrides="":后缀覆盖,去掉整个字符串后面多余的字符串。

foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

<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>
  • collection:指定要遍历的集合:list类型的参数会特殊处理封装在map中,map的key就叫list。
  • item:将当前遍历出的元素赋值给指定的变量。
  • separator:每个元素之间的分隔符。
  • open:遍历出所有结果拼接一个开始的字符。
  • close:遍历出的所有结果拼接一个结束的字符。
  • index:索引。遍历list的时候index是索引,item就是当前的值;遍历map的时候是index表示的就是map的key,item就是map的值。
  • #{变量名}就能取出变量的值也就是当前遍历出的元素

bind

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值