动态 SQL
<where>
标签
看下面这个场景,系统会根据我们的筛选条件,动态组装 where 条件
这种如何实现呢?
接下来我们看代码实现:
需求:传入的用户对象,根据属性做where条件查询,用户对象中属性不为 null 的,都为查询条件。如 username 为 “a”,则查询条件为 where username=“a”
一次性选择所有 where 条件
原有SQL:
接口定义
和Mapper.xml实现
:
修改为动态参数:
单元测试
运行对应测试类方法,观察打印日志:
动态拼接 where 条件
上面的操作是把 where 条件对应的参数一次性都传给接口;
如果我们想像淘宝下面,选一个选项,就出现符合条件的记录,再选一个选项,就根据刚刚的记录做进一步筛选;这样动态的拼接 where 条件
,该如何操作呢?
如果是动态拼接 SQL 中的条件,我们可以考虑 <where>
和<if>
配合使用:
当然,上面还是会存在一个 Bug 的,就是当我们没有给 age 属性传参时,会出现 SQL 拼接错误:
执行对应测试类方法,观察打印日志:
解决动态拼接 SQL出现的 bug
使用<trim>
标签去掉前缀“AND”
这时候,我们就需要结合<trim prefixOverrides="and">
操作,来完成正确的 SQL 拼接:
执行对应测试类方法,观察打印日志,可以发现,程序运行成功:
这时候还存在一个 bug,就是我们什么参数都不传,对应用户筛选条件一个不选就直接查询的情况:
执行对应测试类方法,观察打印日志:
方案一:添加查询条件“1=1”
当查询条件为空时,会多余 where 关键字
,如果我们以去除 where
为思路来修改代码,使用<trim>
标签是无法解决的,我们需要另外再想别的解决方案;
这时候,我们以另一种思路来解决这个问题,也就是多添加一个查询条件:
重新运行对应测试类方法,观察打印日志:
接下来,我们要对参数不同属性分别传参,测试八种不同参数组合
,来测试我们的动态 SQL 是否正确,结果都是通过的:
方案二:使用<where>
标签代替 where 关键字
这时候,我们去掉 where
关键字和 <trim>
标签,使用 <where>
标签包裹拼接的 SQL 条件:
<where>
只会在子元素有内容的情况下才插入 where 关键字,而且会自动去除子句的开头的AND或 OR
重新运行对应测试类,观察打印日志,发现程序运行成功:
我们还要测试八种排列组合下,是否都能运行成功,本文不再演示:
重新运行对应测试类,观察打印日志,发现程序运行成功:
<where>
只会在子元素有内容的情况下才插入 where 子句,而且会自动去除子句的开头的AND或 OR
- 以上标签也可以使用
<trim prefix="where" prefixOverrides="and">
替换,但是此种情况下,当子元素都没有内容时,where关键字也会保留
;
或者使用注解方式: