目录

  • 环境准备
  • 原理解析
  • 源码分析

环境准备



原理解析

  1. 首先创建主查询的RowKey, 根据主查询的数据库值
  2. 读取暂存区, 判断根据key是否可以获取到值, 如果获取到就不需要创建对象,否则创建对象
  3. 填充符合属性, 填充查询评论的数据库值
  4. 将RowKey填充到数据库中, 为了处理resultSet为多个值的情况

从上面的流程可以知道 :
5. 嵌套查询会根据主查询数据进行分组, 下图中根据id进行分组, 填充评论数据, 如果不配置id会默认根据全部的result进行分组, 如果去掉图中的id, 则会抛出异常

  • 存在多个result时, 根据多个result值进行分组
  • 存在一个result时, 根据这个result值进行分组
  • 如果存在id和result, 则只会根据id进行分组
  1. collection中为嵌套查询数据, 默认也会生成一个resultMap

源码分析


走到此方法, 数据库结果集已经查询完成, resultSet中包含三条数据

899行 : 创建一个缓存key, 存入到nestedResultObjects中, nestedResultObjects的作用就是判断主表的数据是否被查询过
因为是第一次查询, 900行肯定为null, 902行为false,
进入909行

417行 : 为null, 进入else逻辑
425行 : 创建一个空对象
429-431 : 为自动映射属性赋值, 看"环境准备中的sql", 只有title属性为自动映射, 为title赋值属性

432行 : 进行结果集映射, 为id值赋值

434行 : 处理嵌套查询, 进入

根据resultMap查询, 生成两个查询条件id和commentDOS, id为普通映射, commentDOS为嵌套映射,
我们进入第二次for循环

946行 : 生成一个key, 根据查询到的评论信息
947行 : 之前生成的key与946行生成的key, 合并成一个联合key
948行 : 为null
950行 : 为返回值赋值一个空集合

952行 : 递归调用getRowValue()方法, 将resultSet中评论部分, 赋值到rowValue中,== 同时将联合key放入到nestedResultObjects中==
954行 : 为metaObject对象赋值,

到此为止, resultSet中的第一行数据数据完毕, 让我们看一下第二行数据的处理逻辑

900行 : 获取的值不为null,

接下来就是进行第二条评论的填充

进入418行的if逻辑
421行的逻辑和第一次分析的逻辑相同

更多推荐

mybatis -- 嵌套查询