mybatisplus遇到的and和or优先级的问题处理


我在测试过程当中发现获取数据信息时候获取到了意想不到的数据

查看了Mybatis的查询语句:

LambdaQueryWrapper<RobotAnswerLibEntity> answerWrapper = new LambdaQueryWrapper<>();
answerWrapper.eq( RobotAnswerLibEntity::getProjectId, projectId );
answerWrapper.eq( RobotAnswerLibEntity::getDeviceSerial, "");
answerWrapper.or();
answerWrapper.eq( RobotAnswerLibEntity::getDeviceSerial, dto.getDeviceSerial());

  

本意是想要 该projectId下,DeviceSerial为""或"输入"的所有数据。

观察它生成的sql如下:

SELECT id,content,tags,device_serial,enable,display,projectid 
FROM tb_robot_answer_lib WHERE
(projectid = 533840063904560 AND device_serial = '123abcdasd123123a' OR device_serial = '')

查询结果:

 

可以看到有很多不属于想要的数据。


问题的根本原因就是在于这个 AND 和 OR 的优先级。关系型运算符优先级高到低为:NOT > AND > OR

所以事实上执行的顺序是 先判断了
projectid = 533840063904560 AND device_serial = '123abcdasd123123a'
后判断了 device_serial = '' ,于是就有了上面的结果。

想改也简单,需要把or左右的两个条件合并到一个()里。具体的代码修正如下:

LambdaQueryWrapper<RobotAnswerLibEntity> answerWrapper = new LambdaQueryWrapper<>();
answerWrapper.eq( RobotAnswerLibEntity::getProjectId, projectId );
answerWrapper
.and(x->x.eq( RobotAnswerLibEntity::getDeviceSerial, "" ).or().eq( RobotAnswerLibEntity::getDeviceSerial, dto.getDeviceSerial() ));

这样生成的sql:

SELECT id,keyword,content,tags,device_serial,
enable,display,projectid
FROM tb_robot_answer_lib
WHERE (projectid = 533840063904560 AND (device_serial = '123abcdasd123123a' OR device_serial = ''))

综上 细节很重要!

posted @ 2022-01-20 15:47  奋斗的大橙子  阅读(1706)  评论(0)    收藏  举报