Mysql中AND、OR的优先级导致的实际项目问题 刺骨的言语ヽ痛彻心扉 2022-10-11 01:00 133阅读 0赞 项目中遇到问题:使用specification 理想的sql:where status=? and (enterprise\_name=? or credit\_code=? or (legal\_person\_name=? and legal\_person\_certificate\_no=?)) specification拼接的sql:where status=? and (enterprise\_name=? or credit\_code=? or legal\_person\_name=? and legal\_person\_certificate\_no=?) List<Predicate> predicateAndList = new ArrayList<>(); predicateAndList.add(criteriaBuilder.equal(root.get("status"), SwindleReportEnterpriseStatusEnum.CONFIRM)); Predicate andStatus = criteriaBuilder.and(predicateAndList.toArray(new Predicate[predicateAndList.size()])); // 组装4个条件的or List<Predicate> predicateOrList = new ArrayList<>(); String enterpriseName = enterpriseBase.getEnterpriseName(); if (StringUtils.isNotBlank(enterpriseName)) { predicateOrList.add(criteriaBuilder.equal(root.get("enterpriseName"), enterpriseName)); } String creditCode = enterpriseBase.getCreditCode(); if (StringUtils.isNotBlank(creditCode)) { predicateOrList.add(criteriaBuilder.equal(root.get("creditCode"), creditCode)); } // 法人信息的过滤 List<Predicate> predicateLegalList = new ArrayList<>(); String legalPersonName = enterpriseBase.getLegalPersonName(); if (StringUtils.isNotBlank(legalPersonName)) { predicateLegalList.add(criteriaBuilder.equal(root.get("legalPersonName"), legalPersonName)); } String legalPersonCertificateNo = enterpriseBase.getLegalPersonCertificateNo(); if (StringUtils.isNotBlank(legalPersonCertificateNo)) { predicateLegalList.add(criteriaBuilder.equal(root.get("legalPersonCertificateNo"), legalPersonCertificateNo)); } // 法人名、证件号 Predicate andLegal = criteriaBuilder.and(predicateLegalList.toArray(new Predicate[predicateLegalList.size()])); predicateOrList.add(andLegal); // 企业名、统一信用代码 Predicate orEnterInfo = criteriaBuilder.or(predicateOrList.toArray(new Predicate[predicateOrList.size()])); return criteriaQuery.where(andStatus, orEnterInfo).getRestriction(); 从打印的sql看最后少了一个括号,这个问题折腾了许久未果,和同事讨论了一下,最终发现是对的,其实以上的两个sql是等价的。 **因为sql里面的and的优先级高于or,所以打印的sql没有括号!!!** 使用本地数据测试: 现需要查询出性别为女的1年级女学生,或者性别为女的2班级女学生。SQL语句如下: 1. `select * from student where sex='女' and grade=1 or class=2` 2. 但是该sql查询出来的结果并不符合要求,执行结果如下: ![eac3a7235a7ae7026c703fb8bc42fc59.png][] 执行结果 执行的结果中还查询出了班级为2的男学生,显然结果是不正确的。 4、修改下SQL语句,添加上括号。如下: 1. `select * from student where sex='女' and (grade=1 or class=2)` 2. 该sql查询出来的结果符合要求,执行结果如下: ![2d26d8a5ce4dceb90f368067fa8f9022.png][] 执行结果 ## 分析 ## 从上面的场景中,问题的关键就在于AND和OR的执行顺序问题。 查阅资料,**关系型运算符优先级高到低为:`NOT >AND >OR`** 如果where 后面有OR条件的话,则OR自动会把左右的查询条件分开。 就如上面场景中的第一条语句,他的查询条件分为两部分(或): 1. `1、sex='女' and grade=1` 2. `2、 class=2` 3. 这也就是查询出1年级的女学生,2班级的学生。不符合最初查询的要求。 那么解决办法就是使用**括号区分执行的顺序** 就如上面场景的第二条语句,查询条件分为两部分(并): 1. `1、 sex='女'` 2. `2、 (grade=1 or class=2)` [eac3a7235a7ae7026c703fb8bc42fc59.png]: /images/20221005/aa4891429f574188882438b114a18958.png [2d26d8a5ce4dceb90f368067fa8f9022.png]: /images/20221005/2d501ffd85dc4ba8be08b56275a754f8.png
相关 Java反射机制在实际项目中的问题示例 在实际项目中,Java反射机制可能会带来一些问题。以下是一些示例: 1. **安全性问题**:反射可以访问任何类的私有信息,如果这些信息被恶意使用,可能导致数据泄露或安全漏洞 爱被打了一巴掌/ 2024年09月16日 06:03/ 0 赞/ 11 阅读
相关 Java泛型在实际项目中的滥用问题 在Java编程中,泛型(Generics)是一种强大的工具,用于创建可以存储任何数据类型的类。然而,在实际项目中,如果过度使用泛型,可能会带来以下问题: 1. **代码冗余* 偏执的太偏执、/ 2024年09月11日 06:42/ 0 赞/ 20 阅读
相关 MYSQL 项目中的实际运用 目录 1、CAST 2、select 1 3、CASE WHEN THEN ELSE END 4、对表字段名的操作 5、派生表 6、嵌套查询 7、while,if 港控/mmm°/ 2023年10月21日 06:50/ 0 赞/ 96 阅读
相关 mysql 查询条件优先级_sql问题之where条件的优先级 在 SQL Server 中,WHERE 子句的表达式先后顺序没有影响。根据运算符的优先级进行运算,相同优先级的运算符两侧的表达式根据评估的代价多寡来运算,先运算代价小的,后运 Bertha 。/ 2022年10月31日 11:00/ 0 赞/ 265 阅读
相关 Mysql中AND、OR的优先级导致的实际项目问题 项目中遇到问题:使用specification 理想的sql:where status=? and (enterprise\_name=? or credit\_code=? 刺骨的言语ヽ痛彻心扉/ 2022年10月11日 01:00/ 0 赞/ 134 阅读
相关 记录实际项目中使用过的Mysql的脚本 一、修改数据库编码及字符集(比较简单,在可视化工具中直接改了,也可以使用如下命令) -- 可直接复制运行 ALTER DATABASE db_name C 绝地灬酷狼/ 2022年10月02日 10:57/ 0 赞/ 115 阅读
相关 MySQL: 14 LRU链表在Buffer Pool实际运行中可能导致的问题 1. LRU链表在Buffer Pool的应用 Buffer Pool在使用过程中如果缓存页都使用了,没有空闲的缓存页时,可以去LRU链表中的尾部找一个最近最少使用的缓存 野性酷女/ 2022年08月29日 10:09/ 0 赞/ 77 阅读
相关 Mysql事务隔离导致的问题 这个功能是要产生一个顺序增长的流水号。简化的代码如下: @Transactional(readOnly=false, propagation=Propaga 绝地灬酷狼/ 2022年06月10日 14:08/ 0 赞/ 130 阅读
相关 dubbox 在实际项目中的使用 dubbox的github地址: [https://github.com/dangdangdotcom/dubbox][https_github.com_dangdangdot 蔚落/ 2022年06月06日 06:56/ 0 赞/ 183 阅读
还没有评论,来说两句吧...