DefaultResultSetHandler的handleRowValues方法中有两个分支,一个用于处理嵌套映射,一个用于处理简单映射,本文讲分析其处理嵌套映射的分支。
handleRowValues方法的定义如下:
public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
if (resultMap.hasNestedResultMaps()) {
//是否存在嵌套结果映射
//RowBounds配置校验
ensureNoRowBounds();
//ResultHandler校验
checkResultHandler();
handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
} else {
//简单映射
handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
}
}
ensureNoRowBounds
safeRowBoundsEnabled属性的含义为:是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。默认值为false
private void ensureNoRowBounds() {
if (configuration.isSafeRowBoundsEnabled() && rowBounds != null && (rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT || rowBounds.getOffset() > RowBounds.NO_ROW_OFFSET)) {
throw new ExecutorException("Mapped Statements with nested result mappings cannot be safely constrained by RowBounds. "
+ "Use safeRowBoundsEnabled=false setting to bypass this check.");
}
}
checkResultHandler
safeResultHandlerEnabled属性的含义为:是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。默认值为true
protected void checkResultHandler() {
if (resultHandler != null && configuration.isSafeResultHandlerEnabled() && !mappedStatement.isResultOrdered()) {
throw new ExecutorException("Mapped Statements with nested result mappings cannot be safely used with a custom ResultHandler. "
+ "Use safeResultHandlerEnabled=false setting to bypass this check "
+ "or ensure your statement returns ordered data and set resultOrdered=true on it.");
}
}
handleRowValuesForNestedResultMap
处理嵌套映射的代码如下,主要用于解决<resultMap>
嵌套<resultMap>
、<resultMap>
嵌套<association>
和<resultMap>
嵌套<collection>
的情况。
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()) {
//处理鉴别器,确定映射所使用的ResultMap对象
final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
//为当前记录创建对应的CacheKey对象
final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
//根据上面创建的从嵌套映射关联的结果对象集合中查询
Object partialObject = nestedResultObjects.get(rowKey);
if (mappedStatement.isResultOrdered()) {
//resultOrdered属性为真
if (partialObject == null && rowValue != null) {
//partialObject为null表示主结果发生变化
//释放nestedResultObjects的空间
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) {
//partialObject为null表示主结果发生变化
storeObject(r