mybatis动态SQL标签: if where choose otherwise trim set foreach
条件判断标签,通过判断参数取值来决定是否使用某个查询条件,基本用法如下:
<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标签解决
<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>
有时候,我们并不想应用所有的条件,而只是想从多个选项中选一个,而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
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>
在动态 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>
动态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>
评论