Mybatis源码之ResultSet结果集处理时序图
详细步骤
PreparedStatementHandler#query
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
// 执⾏SQL
// 结果集处理
return resultSetHandler.handleResultSets(ps);
}
DefaultResultSetHandler#handleResultSets
* 处理statement得到的多结果集(也可能是单结果集,这是多结果集的⼀种简化形式),最终得到结果列表
*
* handleResultSets ⽅法完成了对多结果集的处理。但是对于每⼀个结果集的处理是由handleResultSet⼦⽅法实现的 * @param stmt Statement语句
* @return 结果列表
* @throws SQLException
*/
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").Id());
// ⽤以存储处理结果的列表
final List<Object> multipleResults = new ArrayList<>();
// 可能会有多个结果集,该变量⽤来对结果集进⾏计数
int resultSetCount = 0;
// 可能会有多个结果集,先取出第⼀个结果集
ResultSetWrapper rsw = getFirstResultSet(stmt);
// 查询语句对应的resultMap节点,可能含有多个
List<ResultMap> resultMaps = ResultMaps();
int resultMapCount = resultMaps.size();
// 合法性校验(存在输出结果集的情况下,resultMapCount不能为0)
validateResultMapsCount(rsw, resultMapCount);
// 循环遍历每⼀个设置了resultMap的结果集
while (rsw != null && resultMapCount > resultSetCount) {
// 获得当前结果集对应的ResultMap
ResultMap resultMap = (resultSetCount);
// 进⾏结果集的处理
handleResultSet(rsw, resultMap, multipleResults, null);
// 获取下⼀结果集
rsw = getNextResultSet(stmt);
// 清理上⼀条结果集的环境
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
/
/ 获取多结果集中所有结果集的名称
String[] resultSets = ResultSets();
if (resultSets != null) {
// 循环遍历每⼀个设置resultMap的结果集
while (rsw != null && resultSetCount < resultSets.length) {
// 获取该结果集对应的⽗级resultMap中的resultMapping(注:resultMapping⽤来描述对象属性的映射关系) ResultMapping parentMapping = (resultSets[resultSetCount]);
if (parentMapping != null) {
// 获取被嵌套的resultMap编号
String nestedResultMapId = NestedResultMapId();
ResultMap resultMap = ResultMap(nestedResultMapId);
// 处理嵌套映射
handleResultSet(rsw, resultMap, null, parentMapping);
}
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
}
// 判断是否为单结果集:如果是,则返回结果列表;如果不是则返回结果集列表
return collapseSingleResultList(multipleResults);
}
DefaultResultSetHandler#handleResultSet
* 处理单⼀的结果集
* @param rsw ResultSet 的包装
* @param resultMap resultMap节点信息
* @param multipleResults ⽤来存储处理结果的列表
* @param parentMapping
* @throws SQLException
*/
resultset 遍历private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException { try {
if (parentMapping != null) { // 嵌套的结果
// 向⼦⽅法闯⼊parentMapping。处理结果中的记录
handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
} else { // ⾮嵌套的结果
if (resultHandler == null) {
// defaultResultHandler 能够将结果对象聚合成⼀个列表返回
DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
// 处理结果中的记录
handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
// 添加处理后的结果
multipleResults.ResultList());
} else {
handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
}
}
} finally {
// issue #228 (close resultsets)
ResultSet());
}
}
DefaultResultSetHandler#handleRowValuesForSimpleResultMap
/**
* 处理⾮嵌套映射的结果
* @param rsw 结果集包装
* @param resultMap 结果映射
* @param resultHandler 结果处理器
* @param rowBounds 翻页限制条件
* @param parentMapping ⽗级结果映射
* @throws SQLException
*/
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, Res throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
// 当前要处理的结果集
ResultSet resultSet = ResultSet();
// 根据翻页配置,跳过指定的⾏
skipRows(resultSet, rowBounds);
// 持续处理下⼀条结果,判断条件为;还有结果需要处理 && 结果集没有关闭 && 还有下⼀条结果
while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && ()) {
// 经过鉴别器鉴别,确定经过鉴别器分析的最终要使⽤resultMap
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
// 拿到⼀⾏记录,并且将其转化为⼀个对象
Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
// 把这⼀⾏记录转化出的对象存起来
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
DefaultResultSetHandler#getRowValue
解析ResultMap标签时,会将属性的TypeHandler确定下来
/**
* 将⼀条记录转化为⼀个对象
* @param rsw 结果集包装
* @param resultMap 结果映射
* @param columnPrefix 列前缀
* @return 转化得到的对象
* @throws SQLException
*/
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException {
final ResultLoaderMap lazyLoader = new ResultLoaderMap();
// 创建这⼀⾏记录对应的空对象
Object rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
if (rowValue != null && !hasTypeHandlerForResultObject(rsw, Type())) {
// 根据对象得到其MetaObject
final MetaObject metaObject = wMetaObject(rowValue);
boolean foundValues = this.useConstructorMappings;
// 是否允许⾃动映射未明⽰的字段
if (shouldApplyAutomaticMappings(resultMap, false)) {
// ⾃动映射未明⽰的字段(resultType),映射时的TypeHandler通过属性名与set⽅法参数类型的映射来获取属性的类型,并据此获取对应的TypeHandler foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
}
// 按照明⽰的字段进⾏重新映射(resultMap),解析XML时获取TypeHandler
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
}
return rowValue;
}
以上便是Mybatis中ResultSet结果集处理流程。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论