聊聊MyBatis的嵌套映射的实现
        【摘要】  聊聊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;
        }
    }
步骤解读
这一块的代码比较长,业务逻辑也比较复杂一点,我们将一步一步的解读一下
- 调用skipRows()方法指向需要结果映射的ResultSet
- shouldProcessMoreRows()方法是用来检测是否需要处理行数据,这个方法主要是判断行数是否达到了RowBounds的limit属性的限制
- 也是通过resolveDiscriminatedResultMap()方法用来获取需要映射的ResultMap规则
- 接下来生成CacheKey对象
- 重要的是getRowValue(),这个方法中调用createResultObject()方法创建外面的对象,然后创建MetaObject对象,调用shouldApplyAutomaticMappings()方法看是否需要自动映射,如果开启自动映射就调用applyAutomaticMappings()进行自动映射,然后安装ResultMap中定义的规则进行处理,接着调用applyNestedResultMappings()方法处理嵌套映射,并将映射结果设置到外面对象属性中,然后将外层对象记录nestedResultObjects集合中
- 记录结果到ResultHandler中
除此之外 还有多结果集的处理的代码,这里就不再分析了
总结
对于Mybatis的结果集的映射的功能,我个人觉得不是很简单,涉及的类和方法都比较多,逻辑也比较复杂,对于Mybatis这一块的源码,还需要更加细致和反复的阅读,映射有简单映射和嵌套映射,对应不同的方法和逻辑,这篇对嵌套映射的代码分析也是分析个大概情况,具体还要根据源码来进行理解,今天的文章就先到这里了,文章有什么错误的分析,也请批评和指正,我们共同学习,共同进步,一起走进源码。
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        
        
        - 点赞
- 收藏
- 关注作者
 
             
           
评论(0)