天天看点

sql case when用法_一文打尽动态SQL

兄弟们好,今天我们来聊一下动态

SQL

什么是动态的

SQL

呢?顾名思义,

SQL

可以动态的更新,在我们业务中往往会根据某些条件对数据库中的数据进行一些特殊的更新,而在不是用动态

SQL

技术的时候,这种需求的实现往往很复杂,同时也很难维护。在

MyBatis

中提供了动态

SQL

的支持,他依靠

OGNL

表达式实现了一些条件的判断和数据的迭代。下面我们一起来聊聊

MyBatis

中的动态

SQL

1. 条件语句

1.1 if

if

语句和我们在

Java

中的

if

相同,也是根据条件来执行代码块中的内容。我们来看一下它的语法规则。

上述代码分析:

  • if

    标签中的

    test

    属性中的语句如果为

    true

    则执行标签内的语句。

如果条件为真,则语句为

否则为

我们再来看一下这种情况:

上述代码分析:

如果

test

条件为真,则语句为:

这个时候的语句就违背了

SQL

的语法规则,所以在单独使用

if

语句的时候,往往需要添加如下代码

上述代码分析:

条件为真语句为:

注意:

  • if

    语句可以多次出现,也就是可以进行多重

    if

    判断

1.2 choose、when、otherwise

这个语句类似于我们

Java

中的

IF ELSE

语句。看它的语法

上述代码分析:

  • 执行

    choose

    中的脚本内容
  • 首先判断第一个

    when

    中的

    test

    是否为真,则之后的在

    choose

    中的脚本都不会执行,相当于直接

    break

  • 如果第一个

    when

    的结果为

    false

    ,则进入第二个;
  • 如果第二个

    when

    的结果也为

    false

    ,则直接执行

    otherwise

    中的内容

我们看一下场景的

SQL

第一个

when

为真

第二个

when

为真

前两个都为假

同样,这个语句也会出现上面

if

所出现的当

where

后面没有语句的时候,直接使用条件判断语句,会出现

SQL

的语法错误现象,也需要通过

1=1

来解决。

1.3 CASE WHEN THEN ELSE END

这个语句不是由

MyBatis

提供的,而是原声的

SQL

语句,它可以简化我们很多的操作,租用有点类似于

Switch

上述代码分析:

  • 首先它会使用

    CASE

    后面的变量和

    WHEN

    后面的变量进行比较(这个地方类似于一个

    switch

    语句)
  • 如果第一个

    WHEN

    匹配,则直接返回

    THEN

    以后的值
  • 如果

    WHEN

    中没有匹配的直接返回

    ELSE

    中的值,最后以

    END

    结束

我们再来看它的另一种写法,这个写法类似于一个

IF ELSE

上述代码分析:

  • 直接在

    WHEN

    语句中书写判断式的语句,和

    if ELSE

    相同,也是仅仅执行一个分支

1.4 TRIM WHERE SET

在上面聊

if

choose,when,otherwise

的时候,我们发现了一个问题,当在

where

关键字后面不存在已有条件的时候,会出现

SQL

语句语法出错的情况,我们的解决办法是加上

1=1

让一个条件恒成立。不过

MyBatis

给我们提供了一种解决这种情况的更好的方案。

我们来看一下它是怎么做的?

解析上述代码:

  • where

    元素只有在子元素返回内容的时候才会插入一个

    where

    子句。
  • 如果返回的子句开头是

    AND

    或者

    OR

    的时候,

    where

    元素也会将他们全部去掉

上面是通过

where

元素实现的需求,下面我们看一下通过

trim

元素实现

分析上述代码:

  • trim

    标签的

    prefix

    前缀会在子元素有返回的时候返回一个该属性的属性值
  • prefixOverrides

    属性,会将子句返回的结果中开头为属性值的元素移除,通过管道符

    |

    进行分割(注意空格)

这个时候还需要和大家提一个元素

set

,它常常用于更新操作中,配合条件语句使用,我们来看一下它的用法

分析上述代码:

  • where

    类似,它也是在子句有返回的时候才会添加一个

    SET

    语句

同样它也可以写成

trim

的方式

2. 循环语句

循环语句只有一个

foreach

,这个名字非常熟悉,几乎所有的语言中都这个名字。我们来看一下它的语法

分析上述代码:

  • collection

    是列表的时候
    • item

      代表列表中的元素
    • index

      代表正在迭代的下标
  • collection

    是映射的时候
    • item

      代表的是

      value

    • index

      代表

      key

  • open

    代表了迭代最开始的符号
  • separator

    代表了每一个迭代元素之间的分割符号
  • close

    代表了结束符号

collection

map

的时候

分析上述代码:

  • 上述代码使用了

    CASE WHEN THEN ELSE END

    语法,进行了一个判断筛选

3. 注解使用动态SQL

现在我们业务开发一般都是基于注解的驱动开发,所以需要在注解中直接书写动态

SQL

MyBatis

提供了一个

script

标签帮助我们来注解中书写动态

SQL

语法和

xml

类似,就通过一个

scirpt

标签进行了包裹而以

4. 使用Java代码构建SQL

Mybatis

提供了一个

SQL

构建器,帮助我们可以通过

Java

代码构建一条

SQL

我们来看一下案例

分析上述代码;

  • 这是通过链式语法构建的

    SQL

    • WHERE

      后面默认是

      AND

      ,如果想要使用

      OR

      ,需要在后面写明

      OR()

      (如上例)
  • 通过

    @SelectProvider

    注解,调用

    UserSqlProvider

    中定义的

    SQL

再来看一下另一种写法

分析上述代码:

  • 和上面的相比,它使用了匿名内部类的方式,通过代码块直接调用内部的方法构建

    SQL

    ,所以可以书写

    if

    语句,进行条件判断。

好啦,关于动态

SQL

的内容就只有这些了,兄弟们,下期见

sql case when用法_一文打尽动态SQL

往期原创好文推荐:

lsp都要看的内存模型

抽丝剥茧——状态设计模式

抽丝剥茧——模板方法设计模式

抽丝剥茧——迭代器设计模式

ThreadLocal为啥要用弱引用?不知道

sql case when用法_一文打尽动态SQL