【JavaEE进阶】MyBatis之动态SQL

发布于:2025-02-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

目录

🌲动态SQL

🍃< if >标签

🌳< trim >标签

🎍< where >标签

🍀< set >标签

🌴< foreach >标签

🎋< include >标签


🌲动态SQL

动态SQL是Mybatis的强⼤特性之⼀,能够完成不同条件下不同的sql拼接

可以参考官⽅⽂档:动态 SQL_MyBatis中文网

接下来为大家介绍一些标签来完成sql拼接

首先我们准备数据库userinfo表如下:

🍃< if >标签

在我们实际生活中,当我们在注册时,有时候会面临以下情况

注册分为两种字段:必填字段和⾮必填字段

那如果在添加⽤⼾的时候有不确定的字段传⼊,我们就需要通过拼接的方式来传参,需要这个字段才进行拼接,不需要这个字段就不拼接。

这个时候就需要使⽤动态标签来判断了,⽐如添加的时候性别gender(性别)为⾮必填字段,具体实现如下

我们这里先采用xml方式进行操作:

接口定义如下:

XML代码实现:

XML代码解释:

注意:不可以不进⾏判断,直接把字段设置为null,这种情况下,如果gender字段有默认值,就会设置为默认值

设置gender的情况进行测试:

启动测试:

数据库信息:

未设置gender的情况进行测试:

启动测试:

数据库信息:

如果我们选择使用注解的方式的话,我们需要把上⾯SQL(包括标签),使⽤<script></script>标签括起来就可以

使用如下:

测试单元代码如下:​​​​​​​

启动测试单元:

我们可以发现,与上面使用XML效果是一样的。

查验数据库是否插入成功:

但是呢,这里推荐使用XML方式,因为不容易出错。接下来的演示也全部使用XML的方式。

🌳< trim >标签

上面的插⼊⽤⼾功能,只是有⼀个gender字段可能是选填项,如果有多个字段,就会出现问题。

比如以下程序:

测试单元代码如下:

启动测试单元:

我们发现了报错,上面的sql语句后面多了一个 , 导致查询失败;因为我们没有对gender和phone进行传参,age后面又拼了一个逗号,所以会查询失败;

既然逗号不能方后面,那我们放在前面行不行?当然也是不行的,当没有对username进行传参的话,那么password的前面也会拼接一个逗号(,password),也是会报错的。

此时我们就需要帮助我们去掉前面的逗号或者后面的逗号。

这时候我们就需要使用标签结合标签,对多个字段都采取动态⽣成的⽅式

< trim >标签中有如下属性:​​​​​​​​​​​​​​

  • prefix:表⽰整个语句块,以prefix的值作为前缀
  • suffix:表⽰整个语句块,以suffix的值作为后缀
  • prefixOverrides:表⽰整个语句块要去除掉的前缀
  • suffixOverrides:表⽰整个语句块要去除掉的后缀

那么上述问题代码便可以修改如下:

在以上sql动态解析时,会将第⼀个部分做如下处理:

  • 基于 prefix 配置,开始部分加上 (
  • 基于 suffix 配置,结束部分加上 )
  • 多个组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于suffixOverrides 配置去掉最后⼀个逗号;也就是说用于在每个条件字段后移除多余的逗号。

测试单元代码如下:​​​​​​​

启动测试:​​​​​​​

🎍< where >标签

当我们需要对多个字段进行查询时。

需求:传⼊的⽤⼾对象,根据属性做where条件查询,⽤⼾对象中属性不为 null 的,都为查询条件.如username为"a",则查询条件为where username=“a”

如果我们只使用上面的两种标签,是无法达到效果的。这时候就需要where标签了

定义接口:

XML相关代码如下:

如果上述XML代码编写的话,若username不传参,那么SQL就会是

select * from userinfo where and age and gender    显然这是不正确的SQL语句

但是可以使用上述的<trim>标签的prefixOverrides来去掉,它是一个字符串,想去什么都可以;但是一般不会这么做

如果上述XML代码的参数都不写的话,那么SQL则是

select * from userinfo where     这更是错误的SQL语句

通过where标签修改XML相关代码 如下:

测试所有值都不填 代码如下:​​​​​​​

启动测试:

测试选择性填 代码如下:​​​​​​​

启动测试:

总结:

  • 1. <where></where>标签会自动生成where关键字
  • 2. 如果没有查询条件,会自动去除where关键字
  • 3. 会自动去除最前面的关键字(and or )

不使用<where>标签来完成上述需求

XML相关代码:

启动测试:

🍀< set >标签

需求:根据传⼊的⽤⼾对象属性来更新⽤⼾数据,可以使⽤< set >标签来指定动态内容.

定义接口:

XML相关代码:

当前如果说age为空的话,那么password就会多一个逗号;

生成测试代码如下:

启动测试:

按照之前的学习内容,可以使用<trim>标签来删掉

修改XML相关代码:

启动测试:

查看数据库:

接下来如何通过<set>标签来解决

定义接口:

XML相关代码:

测试相关代码:

启动测试:

查看数据库信息:

可以发现上述两种方式的结果一样。

小结:

  • <set>:动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号.(⽤于update语句中)
  • 以上标签也可以使⽤ <trim prefix="set" suffixOverrides=","> 替换

🌴< foreach >标签

很显然,这个标签是用于循环,比如有批量删除的场景;

对集合进⾏遍历时可以使⽤该标签。标签有如下属性:

  • collection:绑定⽅法参数中的集合,如List,Set,Map或数组对象
  • item:遍历时的每⼀个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串

需求:根据多个userid,删除⽤⼾数据

定义接口:​​​​​​​

XML相关代码如下:

生成测试代码:

启动测试:​​​​​​​

删除数据之前:

删除数据之后:​​​​​​​

🎋< include >标签

在xml映射⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码

我们可以对重复的代码⽚段进⾏抽取,将其通过 < sql > 标签封装到⼀个SQL⽚段,然后再通过< include > 标签进⾏引⽤。

  • < sql > :定义可重⽤的SQL⽚段
  • < include > :通过属性refid,指定包含的SQL⽚段

抽取如下:

通过 < include > 标签在原来抽取的地⽅进⾏引⽤。操作如下:

若后续需要改某一个字段,只需要改<sql>标签即可;但是不一定是完整的SQL,可以是SQL中的某个字段;

启动测试: