我在測試過程當中發現獲取數據信息時候獲取到了意想不到的數據
查看了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 = ''))
綜上 細節很重要!