MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
一、if标签:
1、使用时机:
如果这个时候我们有一个需求,就是根据传入的实体类,判断哪些属性不为空,并以此作为查询条件,那么我们就可以用到该标签。
2、代码示例:
<!-- 根据查询条件进行复合查询 -->
<select id="listUsersByCondition" parameterType="cn.ykf.pojo.User" resultType="cn.ykf.pojo.User">
SELECT * FROM user WHERE 1 = 1
<if test="username != null and username != ''">
AND username LIKE CONCAT('%',#{username},'%')
</if>
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="address != null and address != ''">
AND address = #{address}
</if>
<if test="birthday != null">
AND birthday = #{birthday}
</if>
</select>
3、注意:
- 这里加上 WHERE 1 =1 是防止所有条件都为空时拼接 SQL 语句出错。因为不加上 1 = 1 这个恒等条件的话,如果后面查询条件都没拼接成功,那么 SQL 语句最后会带有一个 WHERE 关键字而没有条件,不符合 SQL 语法。
- <if></if> 标签中 test 属性是必须的,表示判断的条件。其中有几点需要注意:
- 如果 test 有多个条件,那么必须使用 and 进行连接,而不能使用 Java 中的 && 运算符。
- test 中的参数名称必须与实体类的属性保持一致,也就是和 #{参数符号} 保持一致。
- 如果判断条件为字符串,那么除了判断是否为 null 外,最好也判断一下是否为空字符串 '' ,防止 SQL语句将其作为条件进行查询。
二、where标签:
1、代码示例:
<select id="listUsersByCondition" parameterType="cn.ykf.pojo.User" resultType="cn.ykf.pojo.User">
SELECT * FROM user
<where>
<if test="username != null and username != ''">
AND username LIKE CONCAT('%',#{username},'%')
</if>
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="address != null and address != ''">
AND address = #{address}
</if>
<if test="birthday != null">
AND birthday = #{birthday}
</if>
</where>
</select>
2、注意:
- <where></where> 标签只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入 WHERE 子句。而且,若语句的开头为 AND 或 OR,<where></where> 标签也会将它们去除。
- 简单来说,就是该标签可以动态添加 WHERE 关键字,并且剔除掉 SQL 语句中多余的 AND 或者 OR。
三、foreach标签:
1、代码示例:
<!-- 根据id集合查询用户 -->
<select id="listUsersByVo" parameterType="com.itheima.pojo.QueryVo" resultType="com.itheima.pojo.User">
SELECT * FROM user
<where>
<if test="ids != null and ids.size > 0">
<foreach collection="ids" open="AND id IN (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
2、注意:
- <foreach></foreach> 标签用于遍历集合,每个属性的作用如下所示:
collection : 代表要遍历的集合或数组,这个属性是必须的。如果是遍历数组,那么该值只能为 array。
open : 代表语句的开始部份。
close : 代表语句的结束部份。
item : 代表遍历集合时的每个元素,相当于一个临时变量。
separator : 代表拼接每个元素之间的分隔符。
- 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
- SQL 语句中的参数符号 #{id} 应该与 item="id" 保持一致,也就是说,item 属性如果把临时变量声明为 uid 的话,那么使用时就必须写成 #{uid}。