动态 sql 是Mybatis的强⼤特性之⼀,能够完成动态的 sql 语句拼接。
动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。
Mybatis里的动态标签主要有:
<if><trim><where><set><foreach>.
<if>标签:条件选择
一般在我们注册账号的时候,都会有必填字段和⾮必填字段,那么非必填字段就有两种状态了,填或不填。这时候就是动态SQL了,在填的时候我们把数据加上,在不填的时候,我们不加。所以在添加⽤户的时候有不确定的字段传⼊,那么如何实现呢?
解决方法就是<if> 标签,那么if标签如何使用呢?语法规则如下:
<if test="判断条件">
SQL语句
</if>
举个例子:
<insert id="insertBatch">
insert into articleinfo (title,content,uid
<if test="state!=null">
,state
</if>
)
values(#{title},#{content},#{uid}
<if test="state!=null">
,#{state}
</if>
)
</insert>
<trim>标签
前边<if>标签可以实现动态的字段存储,那么和<trim>标签结合起来,可以实现多个字段的动态存储。
trim 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。
- refix:表示整个语句块,以prefix的值作为前缀
- suffix:表示整个语句块,以suffix的值作为后缀
- prefixOverrides:表示整个语句块要去除掉的前缀
- suffixOverrides:表示整个语句块要去除掉的后trim
语法格式如下:
<trim prefix="前缀" suffix="后缀" prefixOverrides="去掉前缀字符" suffixOverrides="去掉后缀字符">
SQL语句
</trim>
使用实例:
<insert id="insertBatch2">
insert into articleinfo
<trim prefix="(" suffix=")" prefixOverrides="," suffixOverrides=",">
<if test="rcount!=null">rcount,</if>
<if test="title!=null">title,</if>
<if test="content!=null">content,</if>
<if test="uid!=null">uid</if>
</trim>
values<trim prefix="(" suffix=")" prefixOverrides="," suffixOverrides=",">
<if test="rcount!=null">#{rcount}, </if>
<if test="title!=null">#{title},</if>
<if test="content!=null">#{content},</if>
<if test="uid!=null">#{uid}</if>
</trim>
</insert>
<where>标签
where用于条件判断,他后边的语句都是条件,但是如果判断语句也为非必填的项,那么在多个非必填的时候用where就可能会导致语法错误。这时候就要用where标签了。
作用:生成where关键字; 去除过于and; 没有where条件就不生成where关键字。
语法如下:
<where>
<if test="判断条件">
AND/OR ...
</if>
</where>
使用实例:
<select id="queryByWhere2" resultType="com.example.springmybatisdemo.model.Article">
select *
from articleinfo
<where>
<if test="uid!=null">
and uid=#{uid}
</if>
<if test="title!=null">
and title=#{title}
</if>
<if test="state!=null">
and state=#{state}
</if>
</where>
</select>
那么,对上边的trim标签熟练的就可以发现,
这里的where标签可以用 <trim prefix="where" prefixOverrides="and">进行替换。
<set>标签
可以使⽤标签来动态指定内容的增加。
作用:生成set关键字; 去除最后一个“,”
语法格式:
<set>
<if test="判断条件">
,
</if>
</set>
使用:
<update id="updateTest2">
update articleinfo
<set>
<if test="uid!=null">
uid=#{uid},
</if>
<if test="content!=null">
content=#{content},
</if>
<if test="title!=null">
title=#{title}
</if>
</set>
</update>
这里可以使⽤ <trim prefix="set" suffixOverrides=",">替换
<foreach>标签
对集合进⾏遍历时可以使⽤该标签。标签有如下属性:
- collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
- item:遍历时的每⼀个对象
- open:语句块开头的字符串
- close:语句块结束的字符串
- separator:每次遍历之间间隔的字符
<foreach item="item" index="index" collection="list|array|map key" open="(" separator="," close=")">
#{item}
</foreach>
使用实例:
<delete id="BatchDelete">
-- delete from articleinfo where uid in(2,3,4,5)
delete from articleinfo where uid in
<foreach collection="list1" open="(" close=")" separator="," item="uid">
#{uid}
</foreach>
</delete>
使用 foreach 标签时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:
- 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list,也可以是用@Param注解给list重命名,传入重命名也可以。
- 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
- 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。