MyBatis3官方文档:http://www.mybatis.org/mybatis-3/zh/configuration.html
一、if元素
1.举例:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter06.mapper.RoleMapper">
<resultMap id="roleResultMap" type="com.ssmr.chapter06.pojo.Role">
<id column="roleNo" property="role_no" />
<id column="role_name" property="roleName" />
<id column="note" property="note" />
</resultMap>
<select id="findRoles1" parameterType="string" resultMap="roleResultMap">
SELECT id,role_name,note
FROM t_role
WHERE 1=1
<if test="roleName != null and roleName != ''">
AND role_name LIKE concat('%', #{roleName}, '%')
</if>
</select>
</mapper>
二、choose、when、otherwise元素
1.举例:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter06.mapper.RoleMapper">
<resultMap id="roleResultMap" type="com.ssmr.chapter06.pojo.Role">
<id column="id" property="id" />
<id column="role_name" property="roleName" />
<id column="note" property="note" />
</resultMap>
<select id="findRoles2" parameterType="role" resultMap="roleResultMap">
SELECT id,role_name,note
FROM t_role
WHERE 1=1
<choose>
<when test="id != null and id != ''">
AND id = #{id}
</when>
<when test="roleName != null and roleName != ''">
AND role_name LIKE concat('%', #{roleName}, '%')
</when>
<otherwise>
AND note is not null
</otherwise>
</choose>
</select>
</mapper>
三、trim、where、set元素
1.where元素
在前面的语句中我们看到where 1=1,这里的1=1如果不加入就会是where and id=........,显然是错误的,但是加上1=1很奇怪。所以我们可以用where来处理。
当where元素里面的条件成立时,才会接入where这个SQL关键字。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter06.mapper.RoleMapper">
<resultMap id="roleResultMap" type="com.ssmr.chapter06.pojo.Role">
<id column="id" property="id" />
<id column="role_name" property="roleName" />
<id column="note" property="note" />
</resultMap>
<select id="findRoles3" parameterType="role" resultMap="roleResultMap">
SELECT id,role_name,note
FROM t_role
<where>
<if test="roleName != null and roleName != ''">
AND role_name LIKE concat('%', #{roleName}, '%')
</if>
<if test="note != null and note != ''">
AND note LIKE concat('%', #{note}, '%')
</if>
</where>
</select>
</mapper>
2.trim元素
有时候要去掉的是一些特殊的SQL语法,比如常见的and、or。而使用trim元素也可以达到预期效果。如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter06.mapper.RoleMapper">
<resultMap id="roleResultMap" type="com.ssmr.chapter06.pojo.Role">
<id column="id" property="id" />
<id column="role_name" property="roleName" />
<id column="note" property="note" />
</resultMap>
<select id="findRoles4" parameterType="string" resultMap="roleResultMap">
SELECT id,role_name,note
FROM t_role
<trim prefix="where" prefixOverrides="and">
<if test="roleName != null and roleName != ''">
AND role_name LIKE concat('%', #{roleName}, '%')
</if>
</trim>
</select>
</mapper>
说明:trim元素意味着要去掉一些特殊的字符串,当时prefix代表的是语句的前缀,而prefixOverrides代表的是需要去掉哪种字符串。上面的写法基本与where是等效的。
3.set元素
Hiberate更新对象时要把所有字段发送给持久对象,来避免发多条SQL的问题,这也会使不需要更新的字段也发送给SQL,显然冗余。
MyBatis采用set元素来避免这样的问题:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter06.mapper.RoleMapper">
<update id="updateRole" parameterType="role">
update t_role
<set>
<if test="roleName != null and roleName != ''">
role_name = #{roleName},
</if>
<if test="note != null and note != ''">
note = #{note}
</if>
</set>
</update>
</mapper>
set元素遇到逗号,它就会把对应的逗号去掉。
当然也可以将它改造成用trim元素来完成:<trim prefix="SET" suffixOverrides","......</trim>
四、foreach元素
往往用于SQL中的in关键字。
public List<Role> findRolesByIds(@Param("idList") List<String> idList);
<select id="findRolesByIds" resultType="role">
SELECT *
FROM t_role
WHERE id IN
<foreach collection="idList" item="id" index="index" open ="(" separator="," close =")">
#{id}
</foreach>
</select>
collection:传递进来的参数名称,可以是数组、LIist、Set等集合。
item:循环中当前的元素。
index:当前元素在集合的位置下标。
open/close:以什么符号将这些集合元素包装起来。
separator:各个元素的间隔符。
注意:在SQL中常常用到in语句,但是对于大量数据的in语句要特别注意,它会消耗大量性能,而且一些数据库的SQL对执行的SQL长度有限制,所以使用它时要预估一下collection对象的长度。
五、用test的属性判断字符串
1.对于字符串的判断,可以通过加入toString()的方法进行比较;它可以判断数值型的参数;对于枚举而言,取决于使用何种typeHandler。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter06.mapper.RoleMapper">
<resultMap id="roleResultMap" type="com.ssmr.chapter06.pojo.Role">
<id column="id" property="id"/>
<id column="role_name" property="roleName"/>
<id column="note" property="note"/>
</resultMap>
<select id="getRoleTest" parameterType="string" resultMap="roleResultMap">
select id, role_name, note
from t_role
<if test="type == 'Y'.toString()">
where 1=1
</if>
</select>
</mapper>
在实践中你会发现判断字符串还有一种方法,如下:(
注意单双引号)
<select id="getRoleTest" parameterType="string" resultMap="roleResultMap">
select id, role_name, note
from t_role
<if test='type == Y" '>
where 1=1
</if>
</select>
六、bind元素
bind元素的作用是通过OGNL表达式去自定义一个上下文变量,这样更方便使用。提高了代码的可移植性。
1.场景:在模糊查询时,MySql数据库常常用到concat,用“%”和参数相连;而在Oracle数据库中则没有,而是使用连接符号“||”。这样Sql就需要两种形式去实现。
bind元素可以不必使用数据库的语言,而是使用MyBatis的动态SQL即可完成。
如下:
public List<Role> findRoles5(String roleName);
<select id="findRoles5" parameterType="string" resultType="com.ssmr.chapter06.pojo.Role">
<bind name="pattern" value="'%' + _parameter + '%'"/>
SELECT id,role_name AS roleName,note
FROM t_role
WHERE role_name like #{pattern}
</select>
_parameter:代表传递进来的参数。
2.Mybatis支持多个参数使用bind元素,如下:
public List<Role> findRoles6(@Param("roleName") String roleName, @Param("note") String note);
<select id="findRoles6" resultType="com.ssmr.chapter06.pojo.Role">
<bind name="pattern_roleName" value="'%' + roleName + '%'"/>
<bind name="pattern_note" value="'%' + note + '%'"/>
SELECT id,role_name AS roleName,note
FROM t_role
WHERE role_name like #{pattern_roleName}
AND note LIKE #{pattern_note}
</select>
3.MyBatis支持对象的传递使用bind元素,如下:
public List<Role> findRoles7(Role role);
<select id="findRoles7" parameterType="com.ssmr.chapter06.pojo.Role" resultMap="roleResultMap">
SELECT id,role_name AS roleName,note
<bind name="pattern_roleName" value="'%' + _parameter.getRoleName() + '%'"/>
<bind name="pattern_note" value="'%' + _parameter.getNote() + '%'"/>
FROM t_role
<where>
<if test="roleName != null and roleName != ''">
AND role_name LIKE #{pattern_roleName}
</if>
<if test="note != null and note != ''">
AND note LIKE #{pattern_note}
</if>
</where>
</select>
注意:使用bind绑定的元素属性值不可以为null,否则会报异常,但是可以为空字符串。为null的话可以在前台自行抛出异常,如果业务中允许为null,则不能使用bind元素。