Mybatis的动态SQL包括以下几个元素:if、choose(一般与when和otherwise一起使用)、trim、foreach、bind、where、set。
1. if 标签
if标签是最常用的判断标签,相当于对java中的if语句,一般与test属性联合使用。
使用场景:在查询条件中,如根据性别查询用户信息,性别就是一个选填条件,可有可无,此时就可以使用if标签进行判断。还可以通过test属性判断输入的参数是否含有某个字符串(参数.toString()方法)
例如:在下面的例子中输入参数为map,test中的name和sex必须等于map中的key;若传入的参数是string类型,则test中的值必须写成”_paramter!=null and _parameter!=””。
<select id="findCount" parameterType="map" resultType="int">
select count(*) from user where role_id=4
<if test="name!=null and ''!=name">
and name like concat('%',#{name},'%')
</if>
<if test="sex!=null and ''!=sex">
and sex = #{sex}
</if>
</select>
**2.choose、when、otherwise元素 **
在映射文件中,choose、when、otherwise三个的功能类似于java中的switch、case、default。具体的业务需求大家在整理的过程中可以对照java中的switch、case、default的业务逻辑进行判断。
<select id="selectStudentByChoose" resultType="Student" parameterType="Student">
select * from student
<!-- 用 choose 选择标签 when 指选择一个 其余就不选了, otherwise 是一定会选择执行的 -->
<where>
<choose>
<when test="username != null and username != ''">
and username=#{username}
</when>
<when test="age != null and age != ''">
and age=#{age}
</when>
<otherwise>
and id=#{id}
</otherwise>
</choose>
</where>
</select>
3.where元素
很多时候,在业务逻辑中,有些查询条件不一定存在,所以在映射文件的配置中,我们是会在查询的条件前加上where 1= 1 (后面就是条件)。没有1=1,若查询条件第一个条件有值,但第二个条件没有值,就会出现where and …,势必会出现语法错误。但是有时候看着where1=1又觉得很奇怪,这个时候就可以使用where标签。
功能:该标签会处理掉sql语句中奇怪的部分。例如在上面的情况叙述中,如果where元素里面的条件成立,则where标签就会在sql语句中添加where关键字,如果查询条件不成立,就会自动把and、or删掉。
<select id="findScoreByCondition" resultType="score" parameterType="map">
SELECT <include refid="score_column"/> from score
<where>
<if test="sname!=null and ''!=sname">
and sname like concat('%',#{sname},'%')
</if>
</where>
<if test="start!=null and size!=null">
limit #{start},#{size}
</if>
</select>
4.trim元素
trim元素就是去掉一些特殊的字符串,其中有prefix,prefixOverrides两个属性,prefix代表的是语句的前缀,prefixOverrides代表的是需要去掉的字符串。(还有suffix=”” suffixOverrides=”“这两个属性,分别代表的是语句的后缀和需要去掉的后缀字符串)。
如下所示,实现的效果与上述的where的效果相同。
<select id="findScoreByCondition" resultType="score" parameterType="map">
SELECT <include refid="score_column"/> from score
<trim prefix="where" prefixOverrides="and">
<if test="sname!=null and ''!=sname">
and sname like concat('%',#{sname},'%')
</if>
</trim>
<if test="start!=null and size!=null">
limit #{start},#{size}
</if>
</select>
5.set元素
在hibernate框架中,常常会出现因为要更新某一个对象的某一个属性,需要发送所有的字段给持久对象。这样的场景在现实中,对网络带宽的消耗较大。最好的方法就是只发送主键和更新的字段值传递给sql,进行更新,这样会提高一定的性能。
mybatis中就可以使用set标签实现。set元素如果遇到逗号,它会把对应的逗号去掉。
<update id="updateUserById" parameterType="map">
update user
<set>
<if test="name!=null and ''!=name">
name = #{name},
</if>
<if test="sex!=null and ''!=sex">
sex = #{sex}
</if>
</set>
</update>
这个时候,如果只更新用户名称,只需要传递用户id和用户名即可,Mybatis会根据参数的规则进行动态sql的组装,查询信息。
**6.foreach元素 **
foreach元素是一个循环语句,作用是遍历集合,它能够很好的支持数组、list、set接口的集合。对这些数据集合进行遍历,往往应用于sql中in关键字的使用。
如根据用户id的数据集合查询用户信息。
<select id="findUserByIds" resultType="user" parameterType="map">
select * from user where id IN
<foreach collection="userList" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
解释:
collection:配置的userList是传递进来的参数名称。
item:配置的是循环中的当前元素
index:当前元素在集合中的位置下标
open、close:配置的是以什么符号将这些元素包装起来
separator:集合中各个元素的间隔符
7.bind元素 **
bind元素的作用是通过OGNL表达式去自定义一个上下文变量**,这样更方便使用。如根据用户名模糊查询用户信息时,常常会用到contact,对’%’和字符串进行连接。然而oracle数据库中没有,oracle中一般使用那个连接符||,所以使用bind元素,提高了代码的可移植性,不要考虑所使用的数据库语言。例如:
<select id="findUser" resultType="user" parameterType="string">
SELECT * from score
<bind name="pattern" value="'%'+name+'%'"/>
where name like #{pattern}
</select>
Mybatis也支持多个bind元素的用法,只要通过bind中name属性分别使用不同的值,value获取不同的值即可。
注:在Mybatis中,如果传递的字符串参数只有一个,则不管在哪个标签中,均使用_parameter;传递的参数是map,则要与key值相同