MyBatis动态SQL
我们知道,有的时候,你需要去拼接SQL,而MyBatis提供对SQL语句动态的组装能力,而且它只有几个基本的元素,下面我们来依次讲讲这些元素;
分为四个元素,if(判断语句),单条件的分支判断
choose(when,otherwise)相当于java中的case when语句,多条件分支判断
trim(where,set)辅助元素,用于处理一些SQL拼接问题
foreach 循环语句,在in语句等列举条件常用;
首先,先讲一下最简单的if元素;
<select id = "findRoles" parameterType = "string" resultMap = "roleResultMap"> select role_no,role_name,note from t_role where 1 = 1 <if test = "roleName != null and roleName != ''" > and role_name like concat('%', #{roleName},'%') </if> </select>
用法简单,test里面是判断的条件,判断里面的条件表达式是否成立;
choose,when,otherwise元素;这是多条件判断语句,相当于switch,case,default元素;
<select id = "findRoles" parameterType = "role" resultMap = "roleResultMap"> select role_no,role_name,note from t_role where l = l <choose> <when test = "roleNo != null and roleNo != ''"> AND role_no = #{roleNo} </when> <when test = "role != null and roleName != ''" > AND role_name like concat('%',#{roleName},'%') </when> <otherwise> AND note is not null </otherwise> </choose> </select>
这个就是多条件分支判断的结果了;
trim,where,set元素;
在这里呢,我们可以想一下where的用法,在上面的语句中,我们在where l = l这里的时候,我们还必须要设置一个where,但是呢,我们可以使用where元素,来替代掉这种方式;下面是代码实现;
<select id = "findRoles" parameterType = "string" resultMap = "roleResultMap"> select role_no, role_name, note from t_role <where> <if test = "roleName != null and roleName != ''"> and role_name like concat ('%',#{roleName},'%') </if> </where> </select>
这样当where元素里面的条件成立的时候,才会加入where这个SQL关键字到组装的SQL里面,否则就不加入;
有时候,我们还需要去掉一些特殊的SQL语法,比如常见的and,or。而使用trim可以达到我们的预期效果 ;
<select id = "findRoles" parameterType = "string" resultMap = "roleResultMap"> select role_no, 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>
其中,trim元素是意味着我们要去掉一些特殊的字符串,prefix代表的是语句的前缀,而prefixOverrides代表的是你需要去掉的那种字符串,上面的写法与where基本一致,也就是说,prefix是指你要加的元素的语句的前缀,而后面就是你的要去掉的字符串了。
下面是set元素,set元素遇到了逗号的话,它会把对应的逗号去掉的。
<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> where role_no = #{roleNo} </update>
这个set元素适用于update语句中,同样的,你也可以把它转换为对应的 trim元素;
<trim prefix = "SET" suffixOverrides = ","></trim>
foreach元素
foreach元素是一个循环语句,他的作用是遍历集合,他能够很好地支持数组和List,Set接口的集合,对此提供遍历的功能。
下面是代码实现;
<select id = "findUserBySex" resultType = "user"> select * from t_user where sex in <foreach item = "sex" index = "index" collection = "sexList" open = "(" separator = "," close = ")"> #{sex} </foreach> </select>
这里要稍微解释一下,
collection配置的sexList是传递进来的参数名称,他可以是一个数组或者List,Set等集合;
item配置的是循环中当前的元素;
index配置的是当前元素在集合的位置下标;
open和close配置的是以什么符号将这些集合元素包装起来;
separator是各个元素的间隔符;
test元素,其实,test就是用它来判断空和非空;
<select id = "getRoleTest" parameterType = "string" resultMap = "roleResultMap"> select role_no, role_name,note from t_role <if test = "type == 'Y'"> where l = l </if> </select>
bind元素,其作用是通过OGNL表达式去自定义一个上下文变量,在进行模糊查询的时候,我们是concat用"%"和参数相连接,然而在Oracle数据库则是用连接符号"||"这样的话就需要两种方式去实现了,我们可以自定义一个;这就是bind元素的作用了;
<select id = "findRole" resultType = "com.learn.capter5.mybatis.bean.RoleBean"> <bind name = "pattern" vlaue = "'%' + _parameter + '%'"/> SELECT id ,role_name as roleName, create_date as createDate ,end_date as endFlag, end_flag as endFlag note FROM t_role where role_name like #{pattern} </select>