兄弟们好,今天我们来聊一下动态
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
的内容就只有这些了,兄弟们,下期见
往期原创好文推荐:
lsp都要看的内存模型
抽丝剥茧——状态设计模式
抽丝剥茧——模板方法设计模式
抽丝剥茧——迭代器设计模式
ThreadLocal为啥要用弱引用?不知道