0
点赞
收藏
分享

微信扫一扫

聊聊MyBatis的结果映射之嵌套映射

@[TOC]

聊聊MyBatis的结果映射之嵌套映射

上篇文章中我们说了一下Mybatis的结果映射的简单映射,这次我们分析一下嵌套映射方法

嵌套映射的处理

对应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这一块的源码,还需要更加细致和反复的阅读,映射有简单映射和嵌套映射,对应不同的方法和逻辑,这篇对嵌套映射的代码分析也是分析个大概情况,具体还要根据源码来进行理解,今天的文章就先到这里了,文章有什么错误的分析,也请批评和指正,我们共同学习,共同进步,一起走进源码。

举报

相关推荐

0 条评论