动态 SQL
动态 SQL 是 MyBatis 的强大特性之一。动态 SQL 可以根据运行时提供的条件,包括 参数值、逻辑判断、循环 等,动态生成SQL语句的各个部分的具体内容。
对动态SQL的学习主要是学习几个重要的标签,下面我们详细介绍:
1、<if> 标签
<if> 标签的作用是根据条件判断是否生成相应的 SQL 片段或语句。
例:根据可选参数插入用户信息
<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>
标签就可能会出错。例如:
<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>
上述这种情况下,如果只传入 password 参数,那么最终拼接的 SQL 语句为:insert into userinfo(,password)……显然,这是一个错误的 SQL 语句。
此时我们可以使用 <trim> 标签结合 <if> 标签,解决上述问题:
trim 标签中的重要属性:
prefix
:表示整个语句块,以prefix的值作为前缀。suffix
:表示整个语句块,以suffix的值作为后缀。prefixOverrides
:表示整个语句块要去除掉的前缀。suffixOverrides
:表示整个语句块要去除掉的后缀。
使用 <trim> 标签解决上述问题:
<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”>替换。
例:根据可选参数查询用户信息
<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=“,”> 替换
例:设置可选参数更新用户信息
<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 批量删除用户信息:
接口:
int deleteByIds(List<Integer> ids);
xml 实现:
<delete id="deleteByIds"> delete from userinfo where id in <foreach collection="ids" open="(" close=")" item="id" separator=","> #{id} </foreach> </delete>