我们在使用Mybatis会经常用到一些动态SQL,Mybatis提供了一些标签供我们使用,本文简单介绍一些常用的标签;
在动态sql中如果出现了大于号(>),小于号(<),大于等于号(>=), 小于等于号(<=),最好将其转换为实体符号,否则,XML可能会出现解析出错问题;特别是对于小于号,在XML中是绝对不能出现的,否则解析一定出错误。
我们可以通过替换符号进行替换:
if标签
对于该标签的执行,当test的值为true时,会讲其包含的SQL片断拼接到SQL语句中;在只是要标签的时候,存在一个比较麻烦的地方,我们需要在where后手工添加1=1的子句,因为如果where后的所有标签条件都是false,并且where子句后没有1=1,则SQL中就后面就一个空的where,SQL就出错看。所以当在where后,要添加一个1=1的子句,以防止这种情况发生。
<select id="getEmpsByConditionIf" resultType="com.yilu.mybatis.Employee">
select * from tbl_employee
where 1=1
<!--
test:判断表达式(OGNL)
从参数中取值进行判断
遇见特殊字符一个写转义字符
-->
<if test="id!=null">
and id=#{id}
</if>
<if test="lastName!=null && lastName!=""">
and last_name like #{lastName}
</if>
<if test="email != null and email.trim()!= """>
and email=#{email}
</if>
<!-- OGNL会进行字符串与数字的转换判断 "0"==0 -->
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</select>
where标签
在上面使用标签的时候,我们需要加一个1=1子句,但是还存在一个问题是,如果数据库很大的时候,会严重影响查询效率;
使用标签在有查询条件的时候,可以自动添加上where子句,没有查询条件时,就不会添加where子句,需要注意的是,第一个if标签中的SQL片段可以不包含and,当然写上也不会报错,系统会将自动去除多余的and,但是其他if中的SQL语句的and,必须要求写上,否则SQL语句拼接会出错误。
<select id="getEmpsByConditionIf" resultType="com.yilu.mybatis.Employee">
select * from tbl_employee
<!-- where 1=1-->
<!-- 方法2:mybatis使用where标签 -->
<!--
test:判断表达式(OGNL)
从参数中取值进行判断
遇见特殊字符一个写转义字符
-->
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="lastName!=null && lastName!=""">
and last_name like #{lastName}
</if>
<if test="email != null and email.trim()!= """>
and email=#{email}
</if>
<!-- OGNL会进行字符串与数字的转换判断 "0"==0 -->
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</where>
</select>
trim标签
我们在使用where标签时,and是写在sql条件片断的前面,如果sql片断后面多出的and或者or where标签不能解决 。
那么当and写在sql后面,我们可以使用标签:
trim 自定义字符串截取的规则
prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":
前缀覆盖: 去掉整个字符串前面多余的字符
suffix="":后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides=""
后缀覆盖:去掉整个字符串后面多余的字符
<select id="getEmpsByConditionTrim" resultType="com.yilu.mybatis.Employee">
select * from tbl_employee
<trim prefix="where" suffixOverrides="and">
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null && lastName!=""">
last_name like #{lastName} and
</if>
<if test="email != null and email.trim()!= """>
email=#{email} and
</if>
<if test="gender==0 or gender==1">
gender=#{gender} and
</if>
</trim>
</select>
choose标签
choose(when,otherwise):分支选择 相当于switch case:break;
对于标签,其会从第一个开始逐个向后进行条件判断,如果出现中test属性为true,则直接结束choose标签,不再向后进行判断查找,如果when标签中的test判断结果都是false,则最后会执行otherwise标签;
在下面的例子中:如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个
<select id="getEmpsByConditionChoose" resultType="com.yilu.mybatis.Employee">
select * from tbl_employee
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null">
last_name like #{lastName}
</when>
<when test="email!=null">
email=#{email}
</when>
<!-- 其他情况查询所有 -->
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
foreach标签
标签用于实现对于数组与集合的遍历。
1.collection:指定要遍历的集合:
list类型的参数会特殊处理封装到map中,map的key就叫list
2. item:将当前遍历出来的元素赋值给指定变量
3.#{变量名} 就能取出变量的值也就是当前遍历出来的元素
4.separator每个元素之间的分隔符
5.open:遍历所有结果拼接一个开始的字符
6.close:遍历所有结果拼接一个结束的字符
<select id="getEmpsByConditionForeach" resultType="com.yilu.mybatis.Employee">
select * from tbl_employee
<if test="list!= null and list.size > 0">
where id in
<foreach collection="list" item="item_id"
separator="," open="(" close=")">
#{item_id}
</foreach>
</if>
</select>
sql标签
抽取可重用的sql片段。方便后面引用
1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
2、include来引用已经抽取的sql;
<select id="selectStudentForeachList" resultType="com.yilu.beans.Student">
<!-- select * from student -->
<include refid="selectColumns"></include>
<if test="list != null and list.size()>0">
<where>
<foreach collection="list" item="stu" open="id in (" close=")" separator=",">
#{stu.id}
</foreach>
</where>
</if>
</select>
<!-- sql片段 -->
<sql id="selectColumns">
select * from student
</sql>