天天看點

在 Mybatis Plus 的單表操作中 in 的相關問題

之前寫過一篇關于 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)
);           

這樣的寫法,咋一看沒什麼問題。開發人員在開發過程中,也沒發現問題,因為語句能執行,查詢有資料。但是到了測試的時候,問題就來了。隻是查一年級學生的資料,結果把全校的學生都查出來了。

會出現這樣的問題,原因有兩個:

  1. 查詢出來的 classIdList 資料為空。
  2. 查詢學生資訊時,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)
);           

以上就是本文的全部内容,希望對大家有幫助。

如果文章有幫助到了你,歡迎點贊、轉發。

如果文章有錯誤的地方,歡迎留言交流。