【MyBatis&MyBatis-plus】使用Mybatis进行多表查询时,查询多条记录但只返回一条

遇到的问题是,如果封装好的select查询语句直接在mysql中运行的话,正确返回list组数

但是,当整合到mybatis里面就只能查询其中一条

大牛给的提示:

需要说明 select的列不需要和对应的resultMap的元素数量一一对应;mybatis使用association 时必须要保证key和association并列,简单来说就是select后面的列很多都可以省但a.m_id, a.s_id不可以省

然后顺藤摸瓜,必须至少有一个和association 并列同级的属性存在且不会重复的 

理论上:

mybatis关联查询,查询结果多条,却只返回一条记录

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

理论联系实际:

1 深坑描述

      我数据库中有三张表,暂且记作 表A,表B,表C,他们之间的关系如下图所示:

这里写图片描述

我创建的持久化类A:

这里写图片描述

当我进行数据库查询的时候,执行的SQL语句是没有问题的,但是worktreatises两个集合总是只有一个数据(按理说work里面应该有3个数据,treatises应该有4个数据)

这里写图片描述

2 深坑原因

产生这种问题的原因,是因为两个数据库的主键都叫做id:如下图

这里写图片描述

这里写图片描述

3 深坑解决

如何解决这种问题:

  • 在Mybatis的配置文件中添加使用别名(注意sql语句也要用别名)
  • 我们修改的只是配置文件,数据库不要改变(注意:数据库不要改变)

  • 修改配置文件为别名

这里写图片描述

这里写图片描述

  • sql语句使用别名查询

这里写图片描述

  • 运行结果正确了

这里写图片描述

4.总结

      通过这个坑我们可以看出来:

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

我的解决方法,本来搜索的是create_time,solution_code,solution.name as solution_name, solution.level, solution.type

看着大神的分析,有可能是因为没有标识区别的id照成的

于是果断添加id字段,完成任务

尼玛,又调试了一天呐,都是泪

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值