聊聊MyBatis的嵌套映射的实现

举报
周杰伦本人 发表于 2022/08/30 13:53:21 2022/08/30
【摘要】 聊聊MyBatis的嵌套映射的实现上篇文章中我们说了一下Mybatis的结果映射的简单映射,这篇文章我们将会分析一下Mybatis的嵌套映射方法,既然是嵌套映射,它的逻辑要比简单映射要复杂一些,我将带您解读一下 嵌套映射的处理对应嵌套映射的处理逻辑是在对应DefaultResultSetHandler的handleRowValuesForNestedResultMap()方法中Defaul...

聊聊MyBatis的嵌套映射的实现

上篇文章中我们说了一下Mybatis的结果映射的简单映射,这篇文章我们将会分析一下Mybatis的嵌套映射方法,既然是嵌套映射,它的逻辑要比简单映射要复杂一些,我将带您解读一下

嵌套映射的处理

对应嵌套映射的处理逻辑是在对应DefaultResultSetHandler的handleRowValuesForNestedResultMap()方法中

DefaultResultSetHandler的handleRowValuesForNestedResultMap()方法:

private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
        final DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
        ResultSet resultSet = rsw.getResultSet();
        skipRows(resultSet, rowBounds);
        Object rowValue = previousRowValue;
        while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
            final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
            final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
            Object partialObject = nestedResultObjects.get(rowKey);
            // issue #577 && #542
            if (mappedStatement.isResultOrdered()) {
                if (partialObject == null && rowValue != null) {
                    nestedResultObjects.clear();
                    storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
                }
                rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
            } else {
                rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
                if (partialObject == null) {
                    storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
                }
            }
        }
        if (rowValue != null && mappedStatement.isResultOrdered() && shouldProcessMoreRows(resultContext, rowBounds)) {
            storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
            previousRowValue = null;
        } else if (rowValue != null) {
            previousRowValue = rowValue;
        }
    }

步骤解读

这一块的代码比较长,业务逻辑也比较复杂一点,我们将一步一步的解读一下

  1. 调用skipRows()方法指向需要结果映射的ResultSet
  2. shouldProcessMoreRows()方法是用来检测是否需要处理行数据,这个方法主要是判断行数是否达到了RowBounds的limit属性的限制
  3. 也是通过resolveDiscriminatedResultMap()方法用来获取需要映射的ResultMap规则
  4. 接下来生成CacheKey对象
  5. 重要的是getRowValue(),这个方法中调用createResultObject()方法创建外面的对象,然后创建MetaObject对象,调用shouldApplyAutomaticMappings()方法看是否需要自动映射,如果开启自动映射就调用applyAutomaticMappings()进行自动映射,然后安装ResultMap中定义的规则进行处理,接着调用applyNestedResultMappings()方法处理嵌套映射,并将映射结果设置到外面对象属性中,然后将外层对象记录nestedResultObjects集合中
  6. 记录结果到ResultHandler中

除此之外 还有多结果集的处理的代码,这里就不再分析了

总结

对于Mybatis的结果集的映射的功能,我个人觉得不是很简单,涉及的类和方法都比较多,逻辑也比较复杂,对于Mybatis这一块的源码,还需要更加细致和反复的阅读,映射有简单映射和嵌套映射,对应不同的方法和逻辑,这篇对嵌套映射的代码分析也是分析个大概情况,具体还要根据源码来进行理解,今天的文章就先到这里了,文章有什么错误的分析,也请批评和指正,我们共同学习,共同进步,一起走进源码。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。