mybatis常用的动态sql标签

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

背景: 我们在编写一些sql查询的过程时,根据条件进行sql的拼接是很麻烦而且容易出错。而mybatis动态sql标签,正好可以解决这个烦人的问题。

mybatis常用的动态sql标签主要有以下几种:

标签作用
if单条件分支,相当于判断语句
choose、when、otherwise多条件分支,相当于Java中的switch语句
set、where、trim辅助条件判断,用于拼接语句
foreach集合进行遍历(尤其是在构建 IN 条件语句的时候)
bind创建一个变量,并将其绑定到当前的上下文

1.if

if 标签最常见情景是根据条件包含 where 子句的一部分,通过判断参数值来决定是否使用某个条件。

<select id="findUser" resultType="User">
  SELECT * FROM user
  WHERE class = '160801'
  <if test="age != null">
    AND age > #{age}
  </if>
</select>

2.choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。choose执行过程中按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when的条件都不满则时,则执行 otherwise 中的 sql。

<select id="getUser" resultMap="User">
    SELECT * from STUDENT WHERE 1=1
    <where>
        <choose>
		    <when test="name!= null">
		      AND name like #{name}
		    </when>
		    <when test="phone != null and address != null">
		      AND age > #{age}
		    </when>
		    <otherwise>
		      AND featured = 1
		    </otherwise>
  		</choose>
    </where>
</select>

3. set、where、trim

3.1 set

在 update 语句中使用 if 标签时,如果最后的 if 没有执行,会导致逗号多余错误。使用 set 标签可以动态地在行首插入set关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。


#如果最后的if没有执行,会导致逗号多余错误。

<update id="updateUser">
  update User SET
      <if test="name != null">
      	name =#{name},
      </if>
      <if test="age != null">
      	age=#{age},
      </if>
      <if test="phone != null">
      	phone =#{phone},
      </if>
      <if test="class != null">
      	class=#{class}
      </if>
  where id=#{id}
</update>
#set标签除掉条件末尾的逗号
<update id="updateUser">
  update User 
      <if test="name != null">
      	name=#{name},
      </if>
      <if test="age != null">
      	age=#{age},
      </if>
      <if test="phone != null">
      	phone=#{phone},
      </if>
      <if test="class != null">
      	adress=#{adress}
      </if>
  where class=#{class}
</update>

3.2 where

where 标签只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。这样我们就不用在where后面加一个1=1了

<select id="findUser" resultType="User">
  SELECT * FROM user
	<where>
	    <if test="class != null">
	         AND class = #{class}
	    </if>
	    <if test="phone != null and adress != null">
	        AND age > #{age}
	    </if>
  </where>
</select>

3.3 trim

set 和 where 其实都是 trim 标签的一种类型, 该两种功能都可以使用 trim 标签进行实现。如果你不满足于where和set实现的功能你就可以使用trim来自定义实现。其中trim有四个主要的属性,分别是:

  • prefix:在sql语句加上前缀
  • suffix:在sql语句加上后缀
  • prefixOverrides:去除指定的前缀内容,比如:prefixOverrides=“AND | OR”,去除sql语句多余的前缀"AND"或者"OR"。
  • suffixOverrides:去除指定的后缀内容,比如:suffixOverrides=",",去除sql语句多余的逗号。

自定义实现3.1的set,去除update语句后缀多余的逗号

<update id="updateUser" resultType="User">
	update user set 
	<trim  suffixOverrides=",">
		<if test="class != null">
	         class = #{class},
	    </if>
	    <if test="phone != null and adress != null">
	        age > #{age},
	    </if>
	</trim> 
	where class=#{class}
</update>

自定义实现3.2的where,去除where子句前缀多余的AND

<select id="findUser" resultType="User">
	select * from user
	<trim prefix="WHERE" prefixOverrides="AND | OR">
		<if test="class != null">
	        AND class = #{class}
	    </if>
	    <if test="phone != null and adress != null">
	        AND age > #{age}
	    </if>
	</trim>
</select>

4.foreach

在进行批量操作的时候,使用比较多的一个场景就是对集合进行遍历,尤其是在构建 IN 条件语句的时候。

<select id="findUser" resultType="User">
  SELECT * FROM user
	where class in
    <foreach item="item" index="index" collection="classList" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

foreach中的属性:

  • collection:通常有三种可选的值,List、数组、map 集合,其中list最为常用
  • item :集合项,也就是集合里面的值
  • index :遍历时的索引变量,也就是下标
  • open :前缀
  • close :后缀
  • separator :分隔符,每个值之间用什么分隔符来分割

5.bind

bind标签表示在表达式以外创建一个变量,并将其绑定到当前的上下文。

<select id="queryUser" resultType="User">
  <bind name="pattern" value="'%' + name + '%'" />
  SELECT * FROM user
  WHERE name LIKE #{name}
</select>

参考文章:mybatis官网文档

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高并发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值