动态 SQL
动态 SQL 是 MyBatis 的强大特性之一。动态 SQL 可以根据运行时提供的条件,包括 参数值、逻辑判断、循环 等,动态生成SQL语句的各个部分的具体内容。
对动态SQL的学习主要是学习几个重要的标签,下面我们详细介绍:
1、<if> 标签
<if> 标签的作用是根据条件判断是否生成相应的 SQL 片段或语句。
例:根据可选参数插入用户信息
java
<insert id="insert2" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into userinfo(username, password
<if test="photo != null">
,photo
</if>
) values (
#{username},
#{password}
<if test="photo != null">
,#{photo}
</if>
)
</insert>
注 : test 中的 字段名,是传入对象中的 属性
,不是数据库字段。
2、<trim> 标签
虽然上面的 <if>
标签可以实现一些动态 SQL,但是如果所有的参数都是可选参数的情况下,只使用 <if>
标签就可能会出错。例如:
java
<insert id="insert2" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into userinfo(
<if test="username != null">
username
</if>
<if test="password != null">
,password
</if>
) values (
<if test="username != null">
#{username}
</if>
<if test="password != null">
,#{password}
</if>
)
</insert>
上述这种情况下,如果只传入 username 参数,那么最终拼接的 SQL 语句为:insert into userinfo(,password)......显然,这是一个错误的 SQL 语句。
此时我们可以使用 <trim>
标签结合 <if>
标签,解决上述问题:
trim 标签中的重要属性:
prefix
:表示整个语句块,以prefix的值作为前缀。suffix
:表示整个语句块,以suffix的值作为后缀。prefixOverrides
:表示整个语句块要去除掉的前缀。suffixOverrides
:表示整个语句块要去除掉的后缀。
使用 <trim> 标签解决上述问题:
java
<insert id="insert2" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into userinfo
<trim prefix="(" suffix=")" prefixOverrides=",">
<if test="username != null">
username
</if>
<if test="password != null">
,password
</if>
</trim>
values
<trim prefix="(" suffix=")" prefixOverrides=",">
<if test="username != null">
#{username}
</if>
<if test="password != null">
,#{password}
</if>
</trim>
</insert>
3、<where> 标签
<where>
标签内部的条件会根据实际情况自动生成 where 子句。<where>
标签会自动去除最前面的"and
"和"or
"关键字。- 根据以上特性,<where>标签也可以使用 <trim prefix="where" prefixOverrides="and"> 或 <trim prefix="where" prefixOverrides="or">替换。
例:根据可选参数查询用户信息
java
<select id="getUserInfoByWhere" resultType="com.example.demo.model.UserInfo">
select * from userinfo
<where>
<if test="id > 0">
id=#{id}
</if>
<if test="photo != null">
and photo=#{photo}
</if>
</where>
</select>
4、<set> 标签
<set>
标签内部的条件会根据实际情况自动生成 set 子句。<set>
标签会自动去除最后面的,
。- 根据以上特性,<set> 标签也可以使⽤ <trim prefix="set" suffixOverrides=","> 替换
例:设置可选参数更新用户信息
java
<update id="updateBySet">
update userinfo
<set>
password=#{password},
<if test="username != null">
username=#{username},
</if>
<if test="photo != null">
photo=#{photo}
</if>
</set>
where id=#{id}
</update>
5、<foreach> 标签
<foreach> 标签用于在 SQL 语句中循环遍历集合或数组,并将其元素应用到 SQL 的特定部分。
下面是 <foreach> 标签中的重要属性:
collection
:绑定方法参数中的集合,如 List,Set,Map或数组对象.item
:遍历时的每⼀个对象.open
:语句块开头的字符串.close
:语句块结束的字符串.separator
:每次遍历之间间隔的字符串.
例如根据用户 id 批量删除用户信息:
接口:
java
int deleteByIds(List<Integer> ids);
xml 实现:
java
<delete id="deleteByIds">
delete from userinfo
where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>