动态SQL的作用
MyBatis的动态SQL主要是为了解决手动拼接sql语句的麻烦。
动态SQL中的元素
– if 判断语句,用于单条件分支判断
– choose(when,otherwise) 相当于switch-case-default,用于多条件判断
– where、set 辅助元素,用于处理SQL拼装
– trim 辅助元素,用于处理特殊字符
– foreach 循环语句,相当于for
1、<if> 元素
在MyBatis中,<if>元素是最常用的判断语句,它类似于Java中的if语句,主要用于实现某些简单的条件选择。
<select id="selectEmp" parameterType="emp" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where 1=1
<if test="empno!=null">
and empno=#{empno}
</if>
<if test="ename!=null and ename!=''">
and ename like '%${ename}%'
</if>
<if test="job!=null and job!=''">
and job like '%${job}%'
</if>
<if test="sal!=null">
and sal=#{sal}
</if>
<if test="deptno!=null">
and deptno=#{deptno}
</if>
</select>
2、<choose>、<when>、<otherwise>元素
相当于switch...case...default语句
<select id="selectEmp" parameterType="emp" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where 1=1
<choose>
<when test="empno!=null">
and empno=#{empno}
</when>
<otherwise>
and deptno=#{deptno}
</otherwise>
</choose>
</select>
3、<where>元素
会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and开头的,MyBatis会把第一个and忽略当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。
<select id="selectEmp" parameterType="emp" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
<where>
<if test="empno!=null">
and empno=#{empno}
</if>
<if test="ename!=null and ename!=''">
and ename like '%${ename}%'
</if>
<if test="job!=null and job!=''">
and job like '%${job}%'
</if>
<if test="sal!=null">
and sal=#{sal}
</if>
<if test="deptno!=null">
and deptno=#{deptno}
</if>
</where>
</select>
4、set元素
当update语句中没有使用if标签时,如果有一个参数为 null,都会导致错误。
当在update语句中使用if标签时,如果前面的if没有执行 ,则或导致逗号多余错误。使用set标签可以将动态的配置 SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
<update id="updateEmp" parameterType="emp">
update emp
<set>
<if test="ename!=null and ename!=''">
ename=#{ename},
</if>
<if test="job!=null and job!=''">
job=#{job},
</if>
<if test="mgr!=null and mgr!=''">
mgr=#{mgr},
</if>
<if test="hiredate!=null">
hiredate=#{hiredate},
</if>
<if test="sal!=null and sal>0">
sal=#{sal},
</if>
<if test="comm!=null and comm>0">
comm=#{comm},
</if>
<if test="deptno!=null">
deptno=#{deptno},
</if>
</set>
where empno=#{empno}
</update>
5、trim元素
<trim>的作用是去除特殊的字符串,它的prefix属性代表语句的前缀,prefixOverrides属性代表需要去除的哪些特殊字符串,功能和<where>基本是等效的。
<select id="selectEmp" parameterType="emp" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
<trim prefix="where" prefixOverrides="and">
<if test="empno!=null">
and empno=#{empno}
</if>
<if test="ename!=null and ename!=''">
and ename like '%${ename}%'
</if>
<if test="job!=null and job!=''">
and job like '%${job}%'
</if>
<if test="sal!=null">
and sal=#{sal}
</if>
<if test="deptno!=null">
and deptno=#{deptno}
</if>
</trim>
</select>
5、foreach元素
– 主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
– foreach元素的属性主要有 item,index,collection, open,separator,close。
– item表示集合中每一个元素进行迭代时的别名
– index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置
– open表示该语句以什么开始
– separator表示在每次进行迭代之间以什么符号作为分隔符
– close表示以什么结束
– collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:
1、如果传入的是单参数且参数类型是一个List的时候, collection属性值为list
<select id="selectEmpByempnos2" parameterType="list"
resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where
empno in
<foreach collection="list" item="i" open="(" close=")" separator=",">
#{i}
</foreach>
</select>
2、如果传入的是单参数且参数类型是一个array数组的时候 ,collection的属性值为array
<select id="selectEmpByempnos" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where
empno in
<foreach collection="array" item="i" open="(" close=")" separator=",">
#{i}
</foreach>
</select>
3、如果传入的参数是多个的时候,我们就需要把它们封装 成一个Map了,当然单参数也可以封装成map,实际上如 果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key。(红字注意!)
<select id="selectEmpByempnos3" parameterType="java.util.Map"
resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where
empno in
<foreach collection="empno" item="i" open="(" close=")" separator=",">
#{i}
</foreach>
</select>
SQL代码片段
通过Sql代码片段,实现sql代码重用
<sql id="sql1">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where
empno in
</sql>
<select id="selectEmpByempnos" resultType="emp">
<include refid="sql1"/>
<foreach collection="array" item="i" open="(" close=")" separator=",">
#{i}
</foreach>
</select>