MyBatis动态SQL

    动态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转义字符

<  ====  &lt;
> ==== &gt;
& ==== &amp;
' ==== &apos;
" ==== &quot;
空格==== &nbsp;

方法二:采用<![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,然后将查询结果映射成关联对象(查询一次)

posted @ 2018-09-08 19:30  不是一个世界的人  阅读(232)  评论(0编辑  收藏  举报