Mybatis进阶之嵌套子查询-循环依赖的揭秘(九)

一、前言:

​ 通过前文Mybatis进阶之简单结果集映射揭秘(八)我们对mybatis查询有了深刻的认识,源码中频繁出现的嵌套子查询究竟为何物?现在我们来揭开它那神秘的面纱,并深究其循环依赖的奥秘.

二、嵌套子查询时序图

avatar

三、嵌套子结果集映射详解

  • CachingExecutor - 缓存执行器

    avatar

  • BaseExecutor - 基础执行器

    特别注意:此时queryStack变量充当整个流程的控制者,EXECUTION_PLACEHOLDER充当一级缓存的空白填充.

    avatar

    avatar

    通过queryFromDatabase进行数据库查询,如下:

    avatar

  • RuseExecutor - 重用执行器

    avatar

  • PreparedStatementHandler - 预处理statement处理器

    avatar

  • DefaultResultSetHandler - 默认结果集处理器

    avatar

    通过handleResultSet进行结果集处理,如下:

    avatar

    通过handleRowValues处理行数据,如下:

    avatar

    通过handleRowValuesForNestedResultMap处理嵌套子查询的结果集行映射,如下:

    avatar

    通过getRowValue对行数据进行映射,如下:

    avatar

    通过applyPropertyMappings对行数据进行手动映射填充,如下:

    avatar

    通过getPropertyMappingValue获取属性映射值时判断其是否是嵌套子查询,如下:

    avatar

    通过getNestedQueryMappingValue获取嵌套查询映射值会判断其加载类型,如下:

    avatar

    avatar

  • ResultLoader - 结果集加载器

    avatar

    整个流程会再次进入BaseExecutor的query中,对queryStack进行累加,只到跳出整个查询.

四、mybatis循环依赖的解决方案

mybatis中BaseExecutor执行器对一级缓存进行管控,利用queryStack标识对最终结果进行处理.一级缓存对没有操作的查询缓存key进行空参填充,在嵌套子查询中会判断是否命中一级缓存,然后将其添加到延迟队列,直到整个查询结束再对其进行延迟队列的加载,填充所有数据.

五、总结

​ mybatis解决循环依赖主要是利用一级缓存和内置的queryStack标识,嵌套子查询的秘密就在于循环依赖的解决,设计美妙绝伦,各位小伙伴得深究其奥秘所在,领略其精华.

​ mybatis如何解析注解配置和xml配置的呢?让我们共同揭秘…

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

请我喝杯咖啡吧~

支付宝
微信