# MyBatis教程 - 10 动态SQL
动态 SQL 是 MyBatis 中的一个强大特性,它允许在编写 SQL 语句时,根据不同的条件动态地改变 SQL 语句的结构。
例如在订单页面,可能会根据订单号、用户名、日期来查询订单,我们可以根据输入哪个条件来将这个条件动态的加入到 SQL 中,这就需要条件判断来动态的改变 SQL 语句。
MyBatis 提供了多个 XML 标签来支持动态 SQL,如 <if>
、<choose>
(<when>
和 <otherwise>
)、<foreach>
、<where>
、<set>
等。下面详细介绍一下这些标签。
# 10.1 if条件判断
<if>
标签可以根据不同的条件来查询信息。
举个栗子:
在 UserMapper.xml
中定义 SQL 映射,如下:
<select id="findByConditions" resultType="User">
SELECT * FROM tb_user
WHERE 1=1
<if test="username != null and username != ''">
AND username = #{username}
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
<if test="age != null">
AND age = #{age}
</if>
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
上面使用了 <if>
标签,判断参数是否为空,当不为空的时候,才拼接 SQL。使用了 1=1
这个永远成立的条件,是为了当条件不满足,没有拼接 SQL 的时候,SQL 也是正确的命令。
针对上面的映射,只需要传递 username
、email
、 age
参数。
所以下面三种方式定义的接口都是可以的:
UserMapper
.java :
/**
* 根据条件查询用户
*/
List<User> findByConditions(User user);
/**
* 根据条件查询用户
*/
List<User> findByConditions(Map<String, Object> map);
/**
* 根据条件查询用户
*/
List<User> findByConditions(@Param("username") String username, @Param("email") String email, @Param("age") Integer age);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
上面三种方式定义的接口,都可以映射到 xml 中的 SQL。
# 10.2 where标签
在上面使用 <if>
标签拼接条件,需要额外使用 1=1
来处理 WHERE
,这样即使所有的查询条件为空,也会有 WHERE
条件判断。
其实我们可以使用 <where>
标签,它可以在生成 SQL 语句时智能地处理 WHERE 条件部分。
<where>
标签的作用:
- 自动添加
WHERE
子句:当 SQL 中有条件时,<where>
标签会自动添加WHERE
子句。 - 自动去除多余的
AND
或OR
:在动态生成的 SQL 中,MyBatis 会自动去除开头的(后面的去不掉)AND
或OR
,避免 SQL 语法错误。
举个栗子,重新写一个多条件查询用户的例子:
内容未完......