动态 SQL
当通过 Mapper XML 文件配置 SQL 时,允许通过 if、choose、foreach 等标签对 SQL进行动态配置。dbVisitor 采用了和 MyBatis 相同的风格。
- <if> 标签,用于判断某个条件满足。
- <choose>、<when>、<otherwise> 标签,多分支条件选择。
- <trim>、<where>、<set> 标签,三个标签可以帮助我们在生成特定 SQL 语句时不会造成纰漏。
- <foreach> 标签,foreach。
- <bind> 标签,使用分页查询机制进行分页查询。
if 标签
<if> 用于判断某个条件满足之后拼接对应的 SQL。
<select id="queryUser">
select * from users
where state = 'ACTIVE'
<if test="age != null">
and age = #{age}
</if>
</select>
单纯的 if 判断可以使用规则来替代,例如:
<select id="queryUser">
select * from users
where state = 'ACTIVE'
</select>
- 了解 AND 规则
标签属性
属性名 | 描述 |
---|---|
test | 必选,一个 ognl 表达式,表达式值是 boolean 表示判断是否成立,若判断成立则执行 SQL 生成。 |
choose (when, otherwise) 标签
当有条件被满足之后会生成对应 <when> 中的 SQL,如果有多个条件同时匹配,只有第一个会生效。若没有匹配任何 <when> 那么 <otherwise> 会生效。
<select id="queryUser">
select * from users
where state = 'ACTIVE'
<choose>
<when test="title != null">and title = #{title}</when>
<when test="content != null">and content = #{content}</when>
<otherwise>and owner = "owner1"</otherwise>
</choose>
</select>
标签属性
<choose> 和 <otherwise> 不含有任何属性。<when> 属性如下:
属性名 | 描述 |
---|---|
test | 必选,一个 ognl 表达式,表达式值是 boolean 表示判断是否成立,若判断成立则执行 SQL 生成。 |
trim (where, set) 标签
<trim>、<where>、<set> 三个标签可以帮助我们在生成特定 SQL 语句时不会造成纰漏。在介绍它们三个之前看一下这个例子:
<select id="queryUser">
select * from users
where
<if test="age != null">
and age = #{age}
</if>
</select>
当 age
属性为空时会生成如下 SQL。
select * from users
where
这是一个无效 SQL,若想避免此类问题可以选择 <where> 。
where 标签(例:1)
当 <if> 条件成立 <where> 中会输出有效内容,一旦出现有效内容 <where> 会自动增加 where 语句。
<select id="queryUser">
select * from users
<where>
<if test="age != null">
age = #{age}
</if>
</where>
</select>
根据 age 值不同,生成的语句将会是下列两种:
select * from users;
select * from users where and age = ?
where 标签(例:2)
下面这个例子 <where> 中多个条件,如果第一个条件匹配失败有可能出现 and 作为开头的情况。
而 <where> 将会自动检测如果是 and
或 or
开头语句则自动去掉它们。
<select id="queryUser">
select * from users
<where>
<if test="age != null">
age = #{age}
</if>
<if test="name != null">
and name = #{name}
</if>
</where>
</select>
set 标签
对于动态更新列语句可以选择 <set>,例如:
<update id="queryUser">
update users
<set>
<if test="age != null">age=#{age},</if>
<if test="name != null">name=#{name},</if>
</set>
where id=#{id}
</update>
trim 标签
<trim> 可以替代 <where> 和 <set>,它的设计目标是为了解决一些特定场景。
使用 trim 标签替代 where 标签
<trim prefix="where" prefixOverrides="and | or">
...
</trim>
使用 trim 标签替代 set 标签
<trim prefix="set" suffixOverrides=",">
...
</trim>
trim 标签的属性
属性名 | 描述 |
---|---|
prefix | 可选 trim 在生成 SQL 时候的前缀。 |
suffix | 可选 trim 在生成 SQL 时候的尾缀。 |
prefixOverrides | 可选 当生成的 SQL 前几个字符匹配这个属性时会被自动裁剪掉,若要配置多个匹配项。需要用 竖线 来分割。 |
suffixOverrides | 可选 当生成的 SQL 后面几个字符匹配这个属性时会被自动裁剪掉,若要配置多个匹配项。需要用 竖线 来分割。 |
foreach 标签
<foreach> 是常用的一个标签,通常是用来构建 in
语句或者 values
的值列表。
<select id="queryByIds">
select * from users
where id in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
单纯的 foreach 可以使用规则来替代,例如:
<select id="queryByIds">
select * from users where @{in,id in :list}
</select>
- 了解 IN 规则
foreach 标签的属性
属性名 | 描述 |
---|---|
collection | 必选 要遍历的数据,可以是数组、集合。 |
item | 必选 在遍历数据过程中,用于标识当前元素的变量名。在标签中可以通过使用这个变量名访问到元素。 |
open | 可选 在开始遍历时候的输出到动态 SQL 的前缀部分。 |
close | 可选 在开始遍历时候的输出到动态 SQL 的尾缀部分。 |
separator | 可选 在遍历的过程中,用于区分每个元素的间隔字符。 |
bind 标签
<bind> 允许通过 ognl
表达式创建一个变量并将其绑定到上下文。例如:
<select id="queryByLike">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
select * from users
where title like #{pattern}
</select>
bind 标签的属性
属性名 | 描述 |
---|---|
name | 必选 要遍历的数据,可以是数组、集合。 |
value | 必选 在遍历数据过程中,用于标识当前元素的变量名。在标签中可以通过使用这个变量名访问到元素。 |