使用动态SQL完成多条件查询
1. 使用if+where实现多条件查询
if:
动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。比如:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.StudentMapper">
<!-- 根据姓名和班级查询 -->
<select id="getStudentByNameAndClasses" resultType="com.po.Student">
select * from t_student where 1=1
<if test="sname!=null">
and sname like concat('%',#{sname},'%')
</if>
<if test="classes!=null">
and classes=#{classes}
</if>
</select>
</mapper>
where :
<select id="findUserByNameAndSex" parameterType="cn.hd.param.QueryVo" resultType="cn.hd.pojo.User">
SELECT * FROM t_user
<where>
<if test="user.name != null and user.name != ''">
AND name LIKE "%"#{user.name}"%"
</if>
<if test="user.sex != null and user.sex != ''">
AND sex=#{user.sex}
</if>
</where>
</select>
2. 使用if+trim实现多条件查询
trim标记是一个格式化的标记,可以完成set或者是where标记的功能
<trim prefix="WHERE" prefixoverride="AND |OR">
<if test="name != null and name.length()>0">
AND name=#{name}
</if>
<if test="gender != null and gender.length()>0">
AND gender=#{gender}
</if>
</trim>
- prefix::前缀,作用是通过自动识别是否有返回值后,在trim包含的内容上加上前缀,如此处的where
- suffix:后缀,作用是在trim包含的内容上加上后缀
- prefixOverides:对于trim包含内容的首部进行指定内容(and | or)的忽略
- suffixOverides:对于trim包含内容的首尾部进行指定内容的忽略
使用动态SQL实现更新操作
1. 使用if+set改造更新操作
<update id="dynamicSetTest" parameterType="Blog">
update t_blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="content != null">
content = #{content},
</if>
<if test="owner != null">
owner = #{owner}
</if>
</set>
where id = #{id}
</update>
2. 使用if+trim改造修改操作
<trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">
<if test="name != null and name.length()>0">
name=#{name} ,
</if>
<if test="gender != null and gender.length()>0">
gender=#{gender} ,
</if>
</trim>
suffix:后缀
suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样)
使用foreach完成复杂查询
1. MyBatis入参数组类型的foreach迭代
- item:表示集合中每一个集合元素进行迭代是的别名(如此处的item)
- index:指定一个名称,用于表示在迭代过程中,每次迭代到的位置(此处未指定)
- open:表示该语句以什么开始(既然是in条件语句,所以比如是以“(”开始)
- separator:表示在每次进行迭代直接以什么符号作为分隔符(既然是in条件语句,所以必然是以“,”作为分隔符)
- close:表示该语句以什么结束(既然是in条件语句,所以比如是以“)”结束)
- collection:最关键最容易出错的属性,需格外注意,该属性必须指定,不同情况下,该属性的值是不一样的,主要有三种情况:
若入参为单参数且参数类型是一个list的时候,collection属性值为list
若入参为单参数且参数类型是一个数组的时候,collection属性值为array
若传入参数为多参数,就需要把它们封装为一个Map进行处理
2. MyBatis入参为List类型的foreach迭代
<select id="dynamicForeachTest" parameterType="java.util.List" resultType="Blog">
select * from t_blog where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
3. Mybatis入参为Map类型的foreach迭代
首先,在mapper对应的dao中使用@param注解,显式指定集合参数类的别名(列表和数组有默认的别名list和array):
第二步,在mapper的xml文件里对map的key进行迭代:
总结
(1) MyBatis接收的参数类型:基本类型、对象、List、数组、Map
(2) 无论MyBatis的入参是那种参数类型,MyBatis都会将参数放在一个Map中,对于单入参的情况:
- 基本类型:变量名作为key,变量值为value,此时生成的Map只有一个元素
- 对象:对象的属性名作为key,属性值为value
- List:默认“list”作为key,该list即为vlaue
- 数组:默认“array”作为key,该数组即为value
- Map:键值不变
4. choose(when,otherwise)
有些时候,我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。