mybatis查询多条记录,只返回最后一条

遇到的问题是,若是封装好的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

解决问题:

修改配置文件别名,查询的时候也使用别名。

结果正确。

总结

  • Mybatis的映射关系是经过查询出来的别名进行反射的。