遇到的問題是,若是封裝好的select查詢語句直接在mysql中運行的話,正確返回list組數java
可是,當整合到mybatis裏面就只能查詢其中一條。mysql
應該是有一個省有多個城市的,卻只返回一個城市。sql
網上查找一份以後發現是由於主表和子表的主鍵字段相同。mybatis
理論:mybatis內部實現機制3d
MyBatis爲了下降內存開銷,採用ResultHandler逐行讀取的JDBC ResultSet結果集的,這就會形成MyBatis在結果行返回的時候沒法判斷之後的是否還會有這個id的行返回,因此它採用了一個方法來判斷當前id的結果行是否已經讀取完成,從而將其加入結果集List,這個方法是:對象
1. 讀取當前行記錄A,將A加入自定義Cache類,同時讀取下一行記錄Bblog
2. 使用下一行記錄B的id列和值爲key(這個key由resultMap的<id>標籤列定義)去Cache類裏獲取記錄內存
3. 假如使用B的key不可以獲取到記錄,則說明B的id與A不一樣,那麼A將被加入到List配置
4. 假如使用B的key能夠獲取到記錄,說明A與B的id相同,則會將A與B合併(至關於將兩個goodsImg合併到一個List中,而goods自己並不會增長)List
5. 將B定爲當前行,同時讀取下一行C,重複1-5,直到沒有下一行記錄
6. 當沒有下一行記錄的時候,將最後一個合併的resultMap對應的java對象加入到List(最後一個被合併goodsImg的Goods)
因此
a. 當結果行是亂序的,例如BBAB這樣的順序,在記錄行A遇到一個id不一樣的曾經出現過的記錄行B時, A將不會被加入到List裏(由於Cache裏已經存在B的id爲key的cahce了)
b. 當結果是順序時,則結果集不會有任何問題,由於 記錄行 A 不可能 遇到一個曾經出現過的 記錄行B, 因此記錄行A不會被忽略,每次遇到新行B時,都不可能使用B的key去Cache裏取到值,因此A必然能夠被加入到List
解決問題:
修改配置文件別名,查詢的時候也使用別名。
結果正確。
總結