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

声明:

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通道传送至数据库管理系统,会引起数据库操作失败。

    为此,映射器为可能出现空子句的场景提供了能够自动修正空子句的元素,如: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>

邮箱:zhaozhiqian001@163.com

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



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫白小猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值