动态 SQL 的概念、种类及分析

本文介绍了MyBatis中的动态SQL概念,包括if、choose、when、otherwise、trim、where、set、foreach、script和bind等标签的用法。动态SQL可根据传入的变量值动态拼接SQL,方便处理复杂的业务逻辑。文章详细分析了动态SQL的执行原理,涉及DynamicSqlSource、MixedSqlNode及其子类的运用。
摘要由CSDN通过智能技术生成

介绍

该笔记是在学习拉勾教育 Java 高薪训练营后,结合课程和老师的视频,自己跟踪源码后做的笔记。

动态 SQL 概念

顾名思义,SQL 是动态拼接成的,根据传入的变量值进行逻辑操作,并动态拼接,方便实现多条件下的数据库操作。 在业务逻辑复杂,即简单 SQL 无法完成时,需要拼接时就要使用动态 SQL。

  以查询为例,会先判断 id 是否不为 0,如果不为 0,才会传入该占位符对应的 id 值。假设 id = 2333,即 “select * from User id = 2333”。如果为 0,则为 “select * from User”。

<select id = "findByCondition" parameterType = "user" resultType = "user">
    SELECT * FROM User
    <where>
        <if test = "id != 0">
            AND id = #{id}
        </if>
    </where>
</select>

动态 SQL 的种类

MyBatis 3 进行精简,有以下几类。

  • if,根据 if 条件来查询。 例子在前面已经给出,是最常用的一种;
  • choose、when、otherwise,从多个条件中选择一个使用。 类似 Java 中的 switch 语句;
  • trim、where、set,trim 标签是用户自定义标签, 可用 trim 标签替换 where 标签和 set 标签;
  • foreach,对集合进行遍历, 会循环执行 sql 的拼接操作,特别是在构建 IN 条件语句时;
  • script,能在带注解的映射器接口类中使用动态 SQL;
  • bind,可以使用 OGNL 表达式创建一个变量并将其绑定到上下文中。
choose、when、otherwise

多个条件选择一个使用,传入 “title” 就按 “title” 查找,传入 “author” 就按 “author” 查找,两个都没有,则默认调用 <otherwise> 标签中的值。

<select id = "findActiveBlogLike" resultType = "Blog">
    SELECT * FROM BLOG WHERE state = "ACTIVE"
    <choose>
        <when test = "title != null">
            AND title LIKE #{title}
        </when>
        <when test = "author != null and author.name != null">
            AND author_name LIKE #{author.name}
        </when>
        <otherwise>
            AND featured = 1
        </otherwise>
    </choose>
</select>
trim、where、set

trim 标签是用户自定义标签,可用 trim 标签替换 where 标签和 set 标签。
  下面例子使用 if 标签,当第一个条件不满足时,SQL 语句为 “SELECT * FROM User WHERE AND user_name = #{userName}”,就会出错。

<select id = "findByCondition" parameterType = "user" resultType = "user">
    SELECT * FROM User WHERE
    <if test = "id != 0">
        id = #{id}
    </if>
    <if test = "userName != null">
        AND user_name = #{userName}
    </if>
</select>

一个解决方法是用 where 标签,会自动覆盖掉第一个 AND 或 OR。另一种等价写法,是使用 trim。

<select id = "findByCondition" parameterType = "user" resultType = "user">
    SELE
  • 7
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值