30 - 多条件查询分析
- 动态SQL
- 缓存机制
- 逆向工程:代码生成器
- page-helper分页插件
- ssm框架整合
动态sql语句非常重要
为什么要用OGNL
因为xml当中,很多东西写不了。
举个例子,xml当中&
这种符号就写不了,需要写成它的实体,叫做amp;
<
和>
是大于小于。
OGNL对咱们的常用符号,做了简单设置。
比如说xml当中&是amp;
,OGNL当中&就是and,OGNL当中||
就是or
。
第一个要讲的是:if where
创建一个java项目:
多条件查询
提问:我设置的条件越多,展示的结果越精确,对不对。
提问:我设置的条件,都应该出现在我的SQL语句中,我没有设置的条件,应不应该出现在我的SQL语句中?
答案是不能够,绝对不能够,我们现在解释一下这个问题。
演示 - EmpMapper
创建了一个EmpMapper,里面有一个多条件查询的方法。
演示 - EmpMapper.xml
演示 - 测试
执行查询的结果如下:
31 - 动态SQL之if
这个时候查询,还能够查询出来吗?
回到京东页面
没有选择的条件,就不能够出现在SQL语句的条件列表中。
如果所有的条件,可能都是一个实体类的属性,你不赋值,它都有默认值的。
如果你没有选择的条件,这些条件还在条件列表中,那么你查询的时候,这些默认值很有可能影响查询结果。
演示 - 查询结果
总结
举个例子理解
比如说有个页面,多条件查询一般都是在列表,基本上都是如此的。
假如说页面当中有四个条件,eid,ename,age,sex。
-
eid是一个文本框,没有设置条件,就是文本框没有值。
-
ename是一个文本框,没有设置条件,就是文本框没有值。
-
age是一个文本框,没有设置条件,就是文本框没有值。
-
sex是一个单选框,没有选择任何一个单选框,就是没有设置。
所以服务器要做个判断,判断eid、ename、age、sex是否有值。
有值就给sql拼接,没有值就不拼接。
这个对参数的判断,是必不可少。
这个判断的逻辑应该是什么呢?
客户端给服务器传输数据有一定规则。
提交表单,表单的action中有请求路径。
第一种情况,不经过form表单,直接地址栏输入请求路径,没有传输任何数据,直接访问服务器。
表单都没有提交,表单当中的数据更没有提交,代表没有一个条件。
没有一个条件的情况下,我们是要查询的是所有的数据。
这个时候服务器获得的,所有参数的值,都是null。
第二种情况,你传了数据,但是没有值。
我在页面当中文本框当中什么都没有写,这个意思就是传了数据,但是没有值。文本框的值是空字符串。
这个时候服务器获得的,是空字符串。
-
文本框不输入,默认值就是空字符串。
-
单选框和复选框,要么选,要么不选,不选就是null,跟没有传是一样的效果。
所以,服务器判断的时候,是需要判断是否是null或空字符串。
总结 - 多条件查询的细节问题 - 【重点】
第一个总结,页面中设置了条件,服务器处理的时候,才可以加入到sql语句中。页面中没有设置条件,服务器处理的时候,一定不要加入到sql语句中。这是因为服务器获取的默认值是会影响查询结果的。
第二个总结,在服务器判断要不要加入到sql语句当中的时候,文本框字段需要判断是否不是null或字符串,单选框复选框判断是否不是null。
引子
如果我们只是学了jdbc,就是逐个使用if代码去判断。
那么我们在mybatis当中,应该怎么做呢?有没有简便的做法。
if标签
报错
上面的映射文件配置后,执行测试,如下报错:
报错总结 - 【重点】
解决报错
第一,修改数据库sex字段的赋值。
第二,修改sql语句。
第三,修改测试代码。
第四,查看执行结果:
第五,去掉一个条件,测试xml中if是否生效。
测试证明生效。
多条件查询sql语句拼接的and问题 - 【重点】
如果上面的sql语句,多条件查询的时候,没有eid这个条件。
那么sql语句就会有点问题,sql语句当中就会多了一个and,语法就错误了。
这个问题,怎么解决呢?
这样测试,就没有问题了。
32 - 动态sql之where
总结 - if标签作用
where标签
原来的sql语句,是这个样子的:
我们把上面的where 1 = 1
这句话去掉。
然后把所有的if标签,都放在where标签内,如下所示:
where标签的作用,就是添加where关键字,并且去掉多余的and。一般情况下,用在我们写条件的地方。
总结 - where标签 【重要】
33 - 动态SQL之trim
if标签和where标签的and小问题 【重要】
假设,我们的sql语句,是如上的写法,and都加在后面啊。
如果sex条件不符合,不拼接到sql中。
那么整个sql语句最终就会多个and。
就会报错,如下所示:
这个问题应该怎么解决呢?
trim标签
我们把where标签,换成trim标签,包裹我们的if代码。
trim标签有4个属性。
- prefix
- suffix
- prefixOverrides
- suffixOverrides
总结 - trim标签 【重要】
演示 - trim标签
如上图蓝色部分的属性,在这个sql中,是不需要设置的。
测试执行,结果正常:
sql拼接的新问题 - 【重要】
如上图所示,上面的sql,如果标号1的条件不符合,sql的最后就多了一个or,如果标号2的条件不符合,sql的最后就多了一个and。
我去,动态拼接的sql,有可能多一个and,也有可能多一个or,这时候咋办呢?
trim标签的细节 【重要】
为了解决上面的问题,在trim标签当中,是这样的写法:
34 - 动态sql之choose
set标签 - 修改操作
简单看看,不演示了。
- set就是把多余的逗号去掉
- 用trim标签,也可以实现。
- 一般情况下,用得不多。
choose标签
choose标签相当于if..else if..else if..else
。
choose标签中的when
,就相当于else if
。
choose标签中的otherwise
,就相当于else
。
演示choose标签 - mapper接口
演示choose标签 - xml映射文件
演示choose标签 - 测试代码
测试结果:
choose标签总结 【重要】
举例子
写一个添加操作,添加性别的时候,从客户端获得的是0和1,添加的时候做一个简单的判断。
如果获得是0,数据库添加为女,如果获得是1,数据库添加为男。
mapper接口如下:
xml当中的sql语句:
测试代码:
测试报错
sql语句当中,男这个字,没有加上单引号。
问题的原因,就是我们在xml当中的when标签内的字符串,没有加上单引号:
报错解决 【重要】
测试第二次报错
这是因为我们的emp实体类当中有五个属性,还有一个did属性。
我们在insert的时候,values当中必须要跟每一个字段全部对应。
修改报错
修改我们的sql语句,变成如下的状态:
第一种方式:
第二种方式:
修改过后,执行正确:
数据库当中,数据添加成功。