原因是:主表和子表的主键字段相同,可以使用别名!这是因为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