动态SQL是MyBatis框架中特性之一,在一些组合查询页面需要根据用户输入的条件生成不同的查询SQL语句,在JDBC中需要在代码中拼接sql,容易出错,MtBatis可解决这种问题
动态SQL标签与JSTL相似,它允许在XML中构建不同的sql语句,常用SQL标签如下:
* 判断标签:if,choose
* 关键字标签:where,set,trim
* 循环标签:foreach
1、if标签是简单条件判断逻辑,满足指定条件时追加if标签内sql语句,不满足时不追加,使用格式如下:
<select>
sql语句1
<if test="条件表达式">
sql语句2
</if>
</select>
if标签最常见的使用在where字句部分,根据不同情况追加不同sql语句
2、choose标签的作用相当于Java的switch语句,基本上跟JSTL中的choose的作用是一样的,通常与when和otherwise搭配使用,使用格式如下:
<select>
sql语句1
<choose>
<when test="条件表达式">
sql语句2
</when>
<when test="条件表达式">
sql语句3
</when>
<otherwise>
sql语句4
</otherwise>
</choose>
</select>
where标签可以在<where>所在的位置输出一个where关键字,而且还可以将后面多余的and或者or关键字去除,使用格式如下:
<select>
select * from emp
<where>
<if test="deptno!=null">
deptno=#{deptno}
</if>
<if test="salary!=null">
and salary=#{salary}
</if>
</where>
</select>
3、set标签主要是用在更新操作时,它的主要功能和where标签相似,主要是在<set>所在的位置输出一个set关键字,而且还可以去除内容结尾中无关的逗号,使用格式如下:
<update>
update emp set
<set>
<if test="ename!=null">
ename=#{ename},
</if>
<if test="salary!=null">
salary=#{salary}
</if>
<if test="hiredate!=null">
hiredate=#{hiredate}
</if>
</set>
where empno=#{empno}
</update>
</update>
4、trim标签主要功能如下:
1)可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix
2)可以把包含内容首部的某些内容过滤,即忽略,也可以把尾部的某些内容过滤,对应的属性是prefixOverrides和suffixOverrides
即trim标签可以替代where标签和set标签,如下:
<!--等价于where标签-->
<trim prefix="where" prefixOverrides="and|or">
......
</trim>
<!--等价于set标签-->
<trim prefix="set" suffixOverrides=",">
......
</trim>
5、foreach标签实现循环逻辑,可以进行一个集合的迭代,主要用在构建IN条件,使用格式如下:
<select>
select * from emp where empno in
<foreach collection="集合" item="迭代变量" open="("close=")" separator=",">
#{迭代变量}
</foreach>
</select>
foreach标签它允许指定一个集合,声明集合项和索引变量,变量可以用在标签内,它允许指定开放和关闭的字符串,在迭代项之间放置分隔符
补充:在XML文件中处理特殊符号,如有些符号xml不识别(“<”)
方法一:采用XML转义字符
< ==== <
> ==== >
& ==== &
' ==== '
" ==== "
空格====
方法二:采用<![CDATA[]]>进行说明,将此内容不进行解析
<if test="">
and <![CDATA[salary<50000.0]]>
</if>
6、MyBatis关联映射
1)主键映射
在做插入操作时,可以由数据库负责主键值生成
主键字段部分的映射可以分为两种情况:
* 数据支持自动递增,如:MYSQL,SQLServer
* 数据库不支持自动递增,如:Oracle
业务:需要返回数据库自动递增的主键值
<!--MySQL-->
<insert id="" parameterType="com.entity.Dept" useGenerateKeys="true" keyProperty="deptno">
insert into dept values(null,#{dname})
</insert>
在<insert>标签指定自动递增属性设置后,MyBatis会在插入操作后将自动递增生成的主键值给keyProperty指定的属性赋值
<!--Oracle-->
<insert id="" parameterType="com.entity.Dept">
<selectKey keyProperty="deptno">
select 序列名.nextval from dual
</selectKey>
insert into dept values(序列名.currval,#{dname})
</insert>
在<insert>标签指定<selectKey>设置后,MyBatis会在插入操作前先执行<selectKey>获取主键值得sql,然后将主键值赋值给指定的主键属性,最后再执行插入的sql
2)多对一映射
在查询时需要获取两张或两张以上关联表的数据,通过关联映射可以由一个对象获取关系对象的信息,例如:查询一个Emp员工对象,可以通过关联映射获取员工所在的部门Dept对象信息
MyBatis的多对一有以下两种不同的实现形式:
* 嵌套查询:通过执行另外一个SQL映射语句来返回关联数据结果(查询两次)
* 嵌套结果查询:执行一个表关联查询SQL,然后将查询结果映射成关联对象(查询一次)
3)一对多映射
当查询某个表的记录信息时,如果关联表有多条相关记录,此时就可以通过一对多映射,例如:查询某个Dept部门对象信息,通过一对多映射获取此部门所有的Emp员工对象信息
MyBatis的一对多有以下两种不同的实现形式:
1、嵌套查询:通过执行另外一个SQL映射语句来返回关联数据结果(查询两次)
2、乔涛结果查询:执行一个表关联查询SQL,然后将查询结果映射成关联对象(查询一次)