在平常的练习中可以随便写sql语句,不要考虑什么。但是到实际开发的过程中,用Mybatis框架,必须写动态sql,这样才显自己的代码才显得合格。
mybatis中常见的动态Sql:
if:
if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择 。举例实现:
<if test="activity.beginTime !=0">
AND <![CDATA[ create_time >= #{activity.beginTime} ]]>
</if>
<if test="activity.endTime !=0">
AND <![CDATA[ create_time <= #{activity.endTime} ]]>
</if>
<if test="activity.title != null and activity.title != ''">
AND title LIKE '%${activity.title}%'
</if>
<if test="activity.editorName != null and activity.editorName != ''">
AND editor_name LIKE '%${activity.editorName}%'
</if>
这条语句的意思非常简单,如果你提供了相应参数,那么就要满足条件,执行if标签后的语句,如果不传入参数,就不执行这条语句,去执行其他的语句,如果同时满足条件,就同时执行if标签之后的sql语句,这是非常有用的一个功能
注意: 在使用 if 标签时,如果在第一个 <if></if>标签前必须有一个where 条件语句, 如果没有要写的条件,可以用 where 1=1来代替。
where:
1. where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。
2. 在使用 <if> 标签时, 有时候没有写的where 语句,就可以直接 <where > 标签, 不在使用 where 1=1 语句
举个栗子看看:
<where>
在此: 通过<where> 标签代替了原来的 where 1=1
<if test="activity.beginTime !=0">
AND <![CDATA[ create_time >= #{activity.beginTime} ]]>
</if>
<if test="activity.endTime !=0">
AND <![CDATA[ create_time <= #{activity.endTime} ]]>
</if>
<if test="activity.title != null and activity.title != ''">
AND title LIKE '%${activity.title}%'
</if>
<if test="activity.editorName != null and activity.editorName != ''">
AND editor_name LIKE '%${activity.editorName}%'
</if>
<choose>
<when test="activity.status !=0">
AND status = #{activity.status}
</when>
<otherwise>
AND status!=0
</otherwise>
</choose>
<choose>
<when test="showStatus == 4">
AND <![CDATA[ begin_time > (select unix_timestamp()*1000) ]]>
</when>
<when test="showStatus == 5">
AND <![CDATA[ begin_time < (select unix_timestamp()*1000)]]> AND <![CDATA[ end_time > (select unix_timestamp()*1000) ]]>
</when>
<when test="showStatus == 6">
AND <![CDATA[ end_time < (select unix_timestamp()*1000) ]]>
</when>
<otherwise>
AND 1 = 1
</otherwise>
</choose>
</where>
set:
set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段。
UPDATE activity
<set>
<if test="activity.title!=null and activity.title != ''">title=#{activity.title},</if>
<if test="activity.content!=null and activity.content!=''">content=#{activity.content},</if>
<if test="activity.banner!=null and activity.banner !=''">banner=#{activity.banner},</if>
<if test="activity.beginTime!=0">begin_time=#{activity.beginTime},</if>
<if test="activity.endTime!=0">end_time=#{activity.endTime},</if>
<if test="activity.updateTime!=0">update_time=#{activity.updateTime},</if>
<if test="activity.address!=null and activity.address!=''">address=#{activity.address},</if>
<if test="activity.updaterId!=0">updater_id=#{activity.updaterId},</if>
</set>
choose:
choose元素的作用就相当于JAVA中的switch语句,通常都是与when和otherwise搭配的,如果满足一个<when>中的条件,就执行这个标签中的sql语句,否则就执行最后otherwise中的sql语句。 并且在一个操作中可以写多个<choose> 标签,相当于可以写多个switch
举个栗子:
<choose>
<when test="activity.status !=0">
AND status = #{activity.status}
</when>
<otherwise>
AND status!=0
</otherwise>
</choose>
<choose>
<when test="showStatus == 4">
AND <![CDATA[ begin_time > (select unix_timestamp()*1000) ]]>
</when>
<when test="showStatus == 5">
AND <![CDATA[ begin_time < (select unix_timestamp()*1000)]]> AND <![CDATA[ end_time > (select unix_timestamp()*1000) ]]>
</when>
<when test="showStatus == 6">
AND <![CDATA[ end_time < (select unix_timestamp()*1000) ]]>
</when>
<otherwise>
AND 1 = 1
</otherwise>
</choose>
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
- 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
- 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
- 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key