我在测试过程当中发现获取数据信息时候获取到了意想不到的数据
查看了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 = ''))
综上 细节很重要!