# 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 语法错误。
举个栗子,重新写一个多条件查询用户的例子:
      内容未完......
    
 