弄浪的鱼

元素 作用 备注
if 判断语句 单条件分支判断
choose、when、otherwise Java中的case..when.. 多条件分支判断
trim、where、set 辅助元素 用于处理 SQL 拼装问题
foreach 循环语句 在in语句等列举条件常用,常用于实现批量操作

if

我们可以使用 <if test="...">进行条件判断,但是按照下面这样的写法就有一个问题,如果两个入参都为空,那么 where 后面就没有语句,不符合 SQL 的规范。

1
2
3
4
5
6
7
8
9
10
11
12
<select id="selectIfOper" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_user a
where
<if test="email != null and email != ''">
a.email like CONCAT('%', #{email}, '%') and
</if>
<if test="sex != null ">
a.sex = #{sex}
</if>
</select>

where

当遇到多个查询条件,使用where 1=1 可以很方便的解决我们的问题,但是这样很可能会造成非常大的性能损失。

因为添加了 “where 1=1 ”的过滤条件之后,数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(即全表扫描) 以比较此行是否满足过滤条件,当表中的数据量较大时查询速度会非常慢;此外,还会存在SQL 注入的风险。

1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="selectIfandWhereOper" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_user a
<where>
<if test="email != null and email != ''">
and a.email like CONCAT('%', #{email}, '%')
</if>
<if test="sex != null ">
and a.sex = #{sex}
</if>
</where>
</select>

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。<where> 其实就是 trim的一种实现。

set

语句集中有值,那就加个 set,同时去掉 set 语句中最后的逗号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<update id="updateIfAndSetOper" parameterType="TUser">
update t_user
<set>
<if test="userName != null">
user_name = #{userName,jdbcType=VARCHAR},
</if>
<if test="realName != null">
real_name = #{realName,jdbcType=VARCHAR},
</if>
<if test="sex != null">
sex = #{sex,jdbcType=TINYINT},
</if>
<if test="mobile != null">
mobile = #{mobile,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
<if test="note != null">
note = #{note,jdbcType=VARCHAR},
</if>
<if test="positionId != null">
position_id = #{positionId,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>

trim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<insert id="insertSelective" parameterType="TUser">
insert into t_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="userName != null">
user_name,
</if>
<if test="realName != null">
real_name,
</if>
<if test="sex != null">
sex,
</if>
<if test="mobile != null">
mobile,
</if>
<if test="email != null">
email,
</if>
<if test="note != null">
note,
</if>
<if test="positionId != null">
position_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="userName != null">
#{userName,jdbcType=VARCHAR},
</if>
<if test="realName != null">
#{realName,jdbcType=VARCHAR},
</if>
<if test="sex != null">
#{sex,jdbcType=TINYINT},
</if>
<if test="mobile != null">
#{mobile,jdbcType=VARCHAR},
</if>
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
<if test="note != null">
#{note,jdbcType=VARCHAR},
</if>
<if test="positionId != null">
#{positionId,jdbcType=INTEGER},
</if>
</trim>
</insert>

参考

动态 SQL