之前寫過一篇關于 in 與 not in 問題的文章( 結合 Mybatis,探讨 Oracle 中 in 與 not in 的陷阱
),現在在擴充一下,談談 Mybatis Plus 單表操作時 in(not in) 的相關問題。
先用一個簡單的例子說明下問題,比如我們要查一年級所有同學的資訊。經常會有下面這樣的寫法:
// 擷取班級ID集合
List<String> classIdList = classMapper.selectList().stream()
.map(Class::getClassId)
.collect(Collectors.toList());
// 擷取學生資訊
List<Student> studentList = studentMapper.selectList(
new QueryWrapper<Student>().lambda()
.in(Student::getClassId, classIdList)
);
這樣的寫法,咋一看沒什麼問題。開發人員在開發過程中,也沒發現問題,因為語句能執行,查詢有資料。但是到了測試的時候,問題就來了。隻是查一年級學生的資料,結果把全校的學生都查出來了。
會出現這樣的問題,原因有兩個:
- 查詢出來的 classIdList 資料為空。
- 查詢學生資訊時,in 條件失效。
之是以有這樣的問題出現,是開發人員在開發過程中有以下一些誤區:
誤區一:查詢語句必定能取到資料。
對于初學者,甚至工作一段時間的開發人員都會有這麼一個誤區,自己寫好的查詢語句一定是對的,而且一定能查出資料。會有這樣自我感覺良好的情況出現,原因來自于開發的模式。在做功能開發的時候,一開始資料庫是沒有任何資料的,需要開發人員手動錄入。而為了使功能可以正常運作,開發人員錄入的資料會保證每個方法都能得到相應的結果,即查詢的時候有值。這就導緻了開發過程中容易漏掉查詢無資料的情況。
誤區二:查詢語句的條件必定生效。
在上面的例子中,因為 classIdList 為空,Mybatis Plus 在組裝 SQL 語句時,是不會把 in 這個條件拼接進來的,進而導緻查詢語句時沒有 in 這個限制條件的。即,當條件 in 中的數組為空時(classIdList 為空),in 是無效的。
避免再次産生類似的問題,也有比較簡單的處理辦法。即,凡是查詢語句,均對查詢結果進行判斷。
将例子中的代碼修改為比較正确的形式,示例如下:
// 擷取班級ID集合
List<String> classIdList = classMapper.selectList().stream()
.map(Class::getClassId)
.collect(Collectors.toList());
if (classIdList.isEmpty()) {
return new ArrayList<>();
}
// 擷取學生資訊
List<Student> studentList = studentMapper.selectList(
new QueryWrapper<Student>().lambda()
.in(Student::getClassId, classIdList)
);
以上就是本文的全部内容,希望對大家有幫助。
如果文章有幫助到了你,歡迎點贊、轉發。
如果文章有錯誤的地方,歡迎留言交流。