Dynamic SQL mybatis动态sql

朱海超
2023-12-01

Dynamic SQL
动态sql是我们开发中家常便饭,但是我们经常会因为格式不正确,多一个, 少一个空格等问题带来诸多烦恼,所以动态sql是我们必须要掌握和了解的
The Dynamic SQL elements should be familiar to anyone who has used JSTL or any similar XML based text processors. In previous versions of MyBatis, there were a lot of elements to know and understand. MyBatis 3 greatly improves upon this, and now there are less than half of those elements to work with. MyBatis employs powerful OGNL based expressions to eliminate most of the other elements:
我们可以知道 mybatis3是使用OGNL表达式
• if
• choose (when, otherwise)
• trim (where, set)
• foreach

1. if

是最常用也是最简单的不太多赘述

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

2. choose, when, otherwise

这个我按照Java中switch理解就可以 switch cas default正好相对应,个人想到的场景比较少,不多写

<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 就是解决我们使用if的时候 如果第一个条件为空了 后面 条件会 在前面多一个 and或者or这样的连接符,导致sql错误
其实就是我们平时填的 where 1=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>
  </where>
</select>

Trim

这个也是很简单但是这个使用的会比较多,个人理解就是将trim快中的sql字符串按照我们的要求进行处理:具体什么要求主要是下面的四个属性决定的

<trim prefix="where" prefixOverrides="and | or" suffix=" " suffixOverrides=" , ">
    
</trim>

Prefix : 顾名思义是前缀,给我们trim快中的sql字符串添加前缀,比如where
PrefixOverrides: 如果trim块中的sql字符串是and 或者or 开头,去掉 and 或者 or
Suffix: 后缀,和prefix 反着理解就可以了
SuffixOverrides: 和prefixoverrides反着理解

Set

一般在update语句中使用,可以将后面多余的, 去掉,此时不用我们关系最后一个多余的,的问题

<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

Foreach大家都知道是一个循环关键字但是我们主要什么情况下使用

  1. 批量插入 insert into value() ()();
  2. 如果条件是一个集合
<foreach collection="list" item="item" 
       index="index" open=" where ids in (" close=")" separator=",">
   
   
</foreach>

Collection: 表示集合如list,map等
Index:如果集合是list index就是List的index,如果是map,index就是key
Item: 如果集合是list,item就是该元素,如果是map, item就是value
Open: 就是foreach sql串开头添加的字符串,
Close:就是foreach sql串结尾添加的字符串,
Separator:是元素之间的分割符

bind

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

生产环境中我们更推荐在参数中直接拼接好

 类似资料: