原因是:主表和子表的主鍵字段相同,可以使用別名!這是因為mybatis的內部實現機制決定的:
MyBatis為了降低內存開銷,采用ResultHandler逐行讀取的JDBC ResultSet結果集的,這就會造成MyBatis在結果行返回的時候無法判斷以后的是否還會有這個id的行返回,所以它采用了一個方法來判斷當前id的結果行是否已經讀取完成,從而將其加入結果集List,這個方法是:
1. 讀取當前行記錄A,將A加入自定義Cache類,同時讀取下一行記錄B
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本身並不會增加)
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
