原创

mybatis动态SQL,各标签使用总结

mybatis动态SQL标签: if where choose otherwise trim set foreach

1. if标签:

条件判断标签,通过判断参数取值来决定是否使用某个查询条件,基本用法如下:

  <select id="testWhere" resultMap="BaseResultMap" parameterType="map">
    select *from employee where  1=1
      --判断age是否等于22
    <if test='age =="22"'>
       and age = #{age}
    </if>
       --name不等于空且不能等于null
    <if test="name != null and name != ''">
       and name like %${name}%
    </if>
</select>

这里 where后面1=1,是为了解决当两个条件都不为true时,sql语句不合法导致报错的问题,也可以通过下面的where标签解决

2. where标签

  1. sql中不用写where
  2. where标签可以过滤掉条件语句中第一个and或or
  <select id="testWhere" resultMap="BaseResultMap" parameterType="map">
    select *from employee
    <where> --执行时,where标签会自动转化为一个where
    <if test="age != null and age != ''">
        age = #{age}
    </if>
    <if test="name != null and name != ''">
        --如果age条件为false,where标签会去掉这个and,让语句正确执行
       and name like %${name}%
    </if>
    </where>
</select>

3. choose、otherwize标签

有时候,我们并不想应用所有的条件,而只是想从多个选项中选一个,而if标签是只要条件为真就会执行sql拼装.这时就需要使用choose标签,choose与java的switch功能类似;

<select id="chooseTest" parameterType="map" resultType="map">
        select * from employee  
        <where>
        <choose>
            <when test="name != null">
                and name = #{name}
            </when>
            <when test="age != null">
                and age = #{age}
            </when>
            <otherwise>
                and address = #{address}
            </otherwise>
        </choose>
        </where>
    </select>

mybatis会依次顺序判断各choose中的条件,当when某个条件满足时,就会跳出choose,即只选择第一个满足条件的when,如果choose中的条件都不满足,则执行otherwise中的语句;

总结:choose otherwise 类似于java的 switch...in case...default

4. trim标签:

trim标签用于控制sql语句的前缀及后缀,其具体属性如下:

属性描述
prefix指定sql语句拼接的前缀
subfix指定sql语句拼接的后缀
prefixOverrides指定sql语句前面要去除的关键字或字符,如AND 逗号 括号等
suffixOverrides指定sql语句后面要去除的关键字或字符

使用方法举例:

使用trim标签去掉多余and或or

<select id="testWhere" resultMap="BaseResultMap" parameterType="map">
--这里trim标签给sql语句添加了前缀where,并会根据条件去掉多余的and或or
select *from employee
<trim prefix="WHERE" prefixOverrides="AND | OR"> 
	<if test="age != null">
	  age = #{age}
	</if> 
	<if test="name != null">
	  AND name like #{name}
	</if>
	<if test="address != null ">
	  or address like #{address}
	</if>
</trim>
</select>

使用trim去掉多余的逗号:

  --这是mybatis-generator插件自动生成的一条插入sql,我们来分析下
  <insert id="insertSelective"  parameterType="com.wg.demo.po.Department">
    insert into department
    --这里添加了前缀为(,后缀为 ),并过滤掉了最后一个逗号
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="deptName != null">
        dept_name,
      </if>
      <if test="descr != null">
        descr,
      </if>
      <if test="createTime != null">
        create_time,  --过滤的逗号在这里
      </if>
    </trim>
    --这里添加了前缀为(,后缀为 ),并过滤掉了最后一个逗号
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="deptName != null">
        #{deptName,jdbcType=VARCHAR},
      </if>
      <if test="descr != null">
        #{descr,jdbcType=VARCHAR},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP}, --过滤的逗号在这里
      </if>
    </trim>
  </insert>

5. set标签

在动态 update 语句中可以使用 set 元素动态更新列

如在update语句中,如果使用if标签,当前面的if条件为false时,就会出现多余逗号的错误,此时用set就可以解决这个问题,如:

  --这是mybatis-generator插件自动生成的条件更新sql
  <update id="updateByPrimaryKeySelective" parameterType="com.wg.demo.po.Employee">
    update employee
    <set>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        age = #{age,jdbcType=VARCHAR},
      </if>
      <if test="gender != null">
        gender = #{gender,jdbcType=SMALLINT},
      </if>
      <if test="deptId != null">
        dept_id = #{deptId,jdbcType=BIGINT},
      </if>
      <if test="address != null">
        address = #{address,jdbcType=VARCHAR},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP}, -- 多余的逗号会被处理掉
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>

6. foreach标签

动态sql的一个常用操作时要求对一个集合进行遍历,通常是在IN条件语句中,如:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT * FROM employee 
  WHERE id in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>
--list中数据为{1,2,3,4}
--sql拼接的结果为: select * from employee where id in (1,2,3,4)		

foreach标签的属性如下:

属性描述
collection表示迭代集合的名称,一般可为list、set、array、map,该参数为必选参数
item本次迭代获取的元素,如collection为list、set、array则item为其中元素,若为map,则item为key-value中的alue,必填参数
open表示该语句以什么开始,最常见的是左括号“(” , 可选参数
close表示该语句以什么结束,最常见的是右括号“)” , 可选参数
separator分隔符,mybatis会在每次迭代后给item后添加一个分隔符,一般为逗号,可选参数
index在list set 数组中,index表示当前迭代元素的下标,在map中index表示key-value中的key,可选参数

在来一个集合为map的例子:

--字典表插入一条数据
<select id = "insertKeyMap" parameterType="map">
	insert into t_key_value(key,value) values
	<foreach collection="map" item="value" index="key" separator=",">
		(#{key},#{value})
	</foreach>
</select>
原创
mybatis
spring boot

评论