[MyBatis]--(4)动态SQL语句--(2)自动修正

版权声明: https://blog.csdn.net/zhaoyaxuan001/article/details/80789401

声明:

Author:赵志乾

Date:2018-6-24

Declaration:All Right Reserved!!!



背景知识:

    1、MyBatis动态SQL语句

    MyBatis作为一个成熟的ORM框架,其通过在映射器中引入3个元素来表征拼接SQL语句的意图。而在其框架代码中,会解析这些元素且保存到配置对象中,并在有调用请求到达时,依据传入的参数和原先解析的动态拼接元素自动拼接成所需的SQL语句。


自动修正

1、场景:

    使用映射器中的if元素、choose元素和foreach元素虽然可以完成SQL语句的动态拼接,但其面临的一个重大问题就是如何保证边界条件下拼出的SQL语句是合法的。例如:where子句中使用if元素给出条件,但如果所有的if元素都判断失败,将导致SQL语句以where结尾。此时的SQL语句是不合法的,如果直接通过JDBC通道传送至数据库管理系统,会引起数据库操作失败。

扫描二维码关注公众号,回复: 3711052 查看本文章

    为此,映射器为可能出现空子句的场景提供了能够自动修正空子句的元素,如:where元素、set元素。这两个元素本质上是两个及其特殊的元素,因为它们均衍生于功能更强大的trim元素。trim元素作为自动修正元素的顶级配置,其提供了4个功能:为SQL片段去前缀、为SQL片段加前缀、为SQL片段去后缀、为SQL片段加后缀。

注:trim元素的前后缀添加生效时刻晚于前后缀去除生效时刻。这个也很容易理解,毕竟这样的设定可以表达更多的场景,如添加、去除、替换。而如果生效顺序相反,则无法表达替换场景。

2、where元素

    使用where元素能够在边界条件下修正空子句,即当where元素包含的SQL片段不为空时,它才会形成where子句,供其父元素做语句的进一步拼接。虽然where元素是自动修正元素的一个,但其功能却是最弱的一个,仅能用于修正空where子句。也就是说当其包含的SQL片段不为空时,需要开发人员保证片段的合法性。例如:where元素包含使用and或or链接的SQL片段,则需要开发人员保证该片段在任何场景下都不能以and或or起始或结束。当可能出现这种场景时,最好使用trim元素。

    where元素应用示例:

<select id="findRole" paramterType="com.zzq.model.Role" resultType="map">
    select id, role_name, note from tbl_role
    <where>
        <if test="roleName!=null and roleName!=''">
            role_name=#{roleName}
        </if>
    </where>
</select>

3、set元素

    同where元素类似,使用set元素能够在边界条件下自动修正空子句,即当set元素包含的SQL片段不为空时,它才会生成set子句,供其父元素做语句的进一步拼接。和where元素不同的是,set元素能够保证其SQL片段不为空时的合法性。这一点的区别源于where子句和set子句语法的不同。因为set子句的不合法前后缀只会是",",而where子句的不合法前后缀却有好几种:如"and"、"or"等。所以where子句通常需要依据具体的应用场景,由开发人员使用trim元素来制定要去除的前后缀。

    set元素应用示例:

<update id="updateRole" paramterType="com.zzq.model.Role">
    update tbl_role
    <set>
        <if test="roleName!=null">
            role_name=#{roleName}
        </if>
    </set>
    where id=#{id}
</update>

4、trim元素

    通过where元素和set元素的介绍,我们对trim元素也有了大概的了解。该元素的属性有4个:prefix、prefixOverrides、suffix、suffixOverrides。各属性作用为:prefix用于指定要添加的前缀、prefixOverrides用于指定要去掉的前缀、suffix用于指定要添加的后缀、suffixOverrides用于指定要去掉的后缀。

    trim元素应用示例:

<update id="updateRole" paramterType="com.zzq.model.Role">
    update tbl_role
    <trim prefix="set" suffixOverride=",">
        <if test="roleName!=null and roleName!=''">
            role_name=#{roleName},
        </if>
        <if test="note!=null and note!=''">
            note=#{note}
        </if>
    </trim>
    where id=#{id}
</update>

邮箱:[email protected]

参考资料:《深入浅出MyBatis技术原理与实践》--杨开振



猜你喜欢

转载自blog.csdn.net/zhaoyaxuan001/article/details/80789401
今日推荐