首页 > 技术文章 > MyBatis动态SQL

zxx123 2018-03-16 11:46 原文

        我们知道,有的时候,你需要去拼接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>

  

推荐阅读