MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。动态 SQL 元素和使用 JSTL 或其他相似的基于 XML 的文本处理器相似。(注:以下示例其他配置均与上篇一致)
1、if:
有时查询数据时,需要用到where来限定多个条件,但是有时也接受在调用该sql命令时传入其中的几个条件值,此时就需要用到if标签来动态的拼接用到的条件,例1:
<select id="selByPriPro" resultType="flower">
select * from flower where 1 = 1
<if test="price != null and price != ''">
and price = #{price}
</if>
<if test="production != null and production != ''">
and production = #{production}
</if>
</select>
此时给production传参与不传参的结果如下,if标签的优越性可见一斑:
2、choose, when, otherwise:
有时我们不想应用所有的条件, 相反我们想选择很多情况下的一种。 与Java中的switch语句相似,MyBatis提供了choose, when, otherwise一组标签来实现该需求。例2:
<select id="selByPriPro" resultType="flower">
select * from flower where 1 = 1
<choose>
<when test="production != null and production != ''">
and production = #{production}
</when>
<otherwise>
and price = #{price}
</otherwise>
</choose>
</select>
两种情况如下:
3、where:
例1中的sql语句用了“where 1 = 1”来避免出现语法错误,但是这样平白无故的比较一下1和1的大小也是要消耗计算机资源的,对于程序而言,计算机资源是宝贵的,那么有没有方法能够避免这个问题呢,答案是有的,可以使用where标签。例3:
<select id="selByPriPro" resultType="flower">
select * from flower
<where>
<if test="price != null and price != ''">
and price = #{price}
</if>
<if test="production != null and production != ''">
and production = #{production}
</if>
</where>
</select>
此时给production与price传参与不传参的结果如下:
4、trim:
trim标签用于:如果trim标签内有满足条件的if子标签,那么拼接该if语句的sql片段的时候在它前面添加指定的内容,或同时删除该sql片段开头的指定内容。例如可以将 例3 改为 例4 :
<select id="selByPriPro" resultType="flower">
select * from flower
<trim prefix="where" prefixOverrides="and">
<if test="price != null and price != ''">
and price = #{price}
</if>
<if test="production != null and production != ''">
and production = #{production}
</if>
</trim>
</select>
此时给production与price传参与不传参的结果如下:
注:trim标签属性介绍
- prefix:为第一个返回的sql片段开头添加指定内容;
- prefixOverrides:为第一个返回的sql片段添加prefix指定的内容之前,先删除该sql片段开头指定的内容;
- suffix:为最后一个返回的sql片段末尾添加指定内容;
- suffixOverrides:为最后一个返回的sql片段添加prefix指定的内容之前,先删除该sql片段末尾指定的内容;
5、bind:
bind是个单标签,它用于对接受的参数做进一步的修改以符合sql语句的需要,常用于进行模糊查询时为接受的参数拼接“%”。例5:
<select id="selByPriPro" resultType="flower">
<bind name="pattern" value="'%' + production + '%'"/>
select * from flower where production like #{pattern}
</select>
将“亚洲”作为参数传递给production,结果如下:
6、foreach:
foreach标签用来遍历集合中的内容,每遍历一次对遍历到的数据进行修改拼接到sql语句中,常用于in查询。例6:
<select id="selByIn" resultType="flower">
select * from flower where name in
<foreach collection="names" open="(" close=")" separator="," item="name" index="index">
#{name}
</foreach>
</select>
用包含“矮牵牛”,“百日草”,“樱花”的List集合测试结果如下:
注:foreach 标签属性介绍
- collection:接收的集合参数;
- open:遍历开始前先拼接上指定的内容;
- close:遍历结束后再拼接上指定的内容;
- separator:为每次遍历拼接的内容指定分隔符;
- item:将每次遍历到的数据赋给指定的变量;
- index:用于记录遍历的次数,从0开始。
7、set:
与其他标签不同,set标签是专门为修改数据提供的标签,set 标签可以被用于动态更新包含的列,而不包含不需更新的。例7:
<update id="upd" parameterType="map">
update flower
<set>
<trim suffixOverrides=",">
<if test="name != null">name = #{name}, </if>
<if test="price != null">price = #{price}, </if>
<if test="production != null">production = #{production},</if>
</trim>
</set>
where id = #{id}
</update>
测试修改4号花的信息,结果如下: