MyBatis 动态SQL

动态 SQL

  • MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。—》官方说法
  • 有那些动态标签呢?
    • if 判断标签
    • choose (when, otherwise) 选择标签
    • trim (where, set) 字符拼接和去过滤and or
    • foreach 循环

if 判断

传入一个参数

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

假如title不为空,则传入titel

传入两个参数

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’ 
  <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>

choose, when, otherwise 类似于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>

title有值就按照title查找,

author.name有值就按照author.name查找,

两者都没有则写入AND featured = 1;(记住只能三选一。switch你懂的)

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>
  • 假如没有一个参数有值,就会变成
SELECT * FROM BLOG
WHERE

查询失败

  • 第二个参数有值,其他没有值
SELECT * FROM BLOG
WHERE 
AND title like ‘someTitle’

查询失败

  • 解决方案一:

    用where包含if,至少有一个参数有值才会出现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>
  • 解决方案二:利用trim标签
    • prefix=”“:前缀:trim标签体中是整个字符串拼串后的结果。prefix给拼串后的整个字符串加一个前缀。
    • prefixOverrides=”“:前缀覆盖: 去掉整个字符串前面多余的字符。
    • suffix=”“:后缀:suffix给拼串后的整个字符串加一个后缀。
    • suffixOverrides=”“:后缀覆盖:去掉整个字符串后面多余的字符。
<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG 
  <trim prefix="WHERE" prefixOverrides="AND | OR "> 
    <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>
  </trim>
</select>
  • 解决方案三:1=1 (推荐很方便)
<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG 
  WHERE 1=1
    <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>

是不是很有意思!

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和where有类似的功能,set会自动忽略子句结尾中的“,”

假如你想用trim的也行

<update id="updateAuthorIfNecessary">
  update Author
    <trim prefix="SET" suffixOverrides=",">
      <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>
    </trim>
  where id=#{id}
</update>

foreach

  • 集合遍历

    • collection表示数据类型,List就是list,array就是array,
    • item表示集合中每一个元素进行迭代时的别名。
    • index指定一个名字,用于表示在迭代过程中,每次迭代到的位置。
    • open表示该语句以什么开始。
    • separator表示在每次进行迭代之间以什么符号作为分隔符。
    • close表示以什么结束。
  • 批量查询

<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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值