1. ResultSetHandler结果集处理器的生成
public ResultSetHandler newResultSetHandler(用来初始化DefaultResultSetHandler的入参) {
ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler,
resultHandler, boundSql, rowBounds);
resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
return resultSetHandler;
}
备注:SqlSession的四大对象在Configuration中都有提供对应的实例生成方法,都需要注意拦截器对底层的影响。
2. 查询结果集
SqlSession中执行步骤的最后处理,其余步骤处理可参考:https://blog.csdn.net/lichunericli/article/details/82563628;
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.<E> handleResultSets(ps);
}
3. 结果集的解析处理
public List<Object> handleResultSets(Statement stmt) throws SQLException {
final List<Object> multipleResults = new ArrayList<>();
// 通常情况下ResultMap的结果集是唯一的,
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
while (rsw != null && resultMapCount > resultSetCount) {
handleResultSet(rsw, resultMap, multipleResults, null);
}
// 对ResultSet的结果集的处理
String[] resultSets = mappedStatement.getResultSets();
if (resultSets != null) {
while (rsw != null && resultSetCount < resultSets.length) {
if (parentMapping != null) {
handleResultSet(rsw, resultMap, null, parentMapping);
}
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}
private void handleResultSetrsw, resultMap, List<Object> multipleResults, ResultMapping parentMapping){
//将查询到的每个字段和Bean实体中的属性对应起来,生成一个Result对象
handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
//结果映射对象及值添加到multipleResults中
multipleResults.add(defaultResultHandler.getResultList());
// 需要注意关闭ResultSet
closeResultSet(rsw.getResultSet());
}
public void handleRowValues(rsw, resultMap, ResultHandler<?> resultHandler, rowBounds, parentMapping){
if (resultMap.hasNestedResultMaps()) {
// 结果嵌套,类似JPA中的级联查询【待确定】
handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
} else {
// 简单Object对象的返回
handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
}
}
private void handleRowValuesForSimpleResultMaprsw, resultMap, ResultHandler<?> resultHandler, rowBounds,
ResultMapping parentMapping)throws SQLException {
// 跳过RowBounds设置的offset值
skipRows(rsw.getResultSet(), rowBounds);
// 判断数据是否小于limit,如果小于limit的话就不断的循环取值
while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
}
}
// GET VALUE FROM ROW FOR SIMPLE RESULT MAP,结果的映射对象
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException {
// 创建结果对象,获取配置的resultMap的字段与表中数据的映射关系,通过反射获取结果,TypeHandler在此处得到体现
Object rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
final MetaObject metaObject = configuration.newMetaObject(rowValue);
boolean foundValues = this.useConstructorMappings;
// 用于判断是否是bean实体变量和表中字段自动映射:AutoMappingBehavior[NONE,PARTIAL,FULL]
if (shouldApplyAutomaticMappings(resultMap, false)) {
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
}
// 属性值的映射
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
}
return rowValue;
}
// 由源码可知,ResultHandler的原理实现几乎是围绕着createResultObject方法而展开,其余的源码实现几乎都是装饰。
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes,
List<Object> constructorArgs, String columnPrefix) throws SQLException {
final Class<?> resultType = resultMap.getType();
final MetaClass metaType = MetaClass.forClass(resultType, reflectorFactory);
final List<ResultMapping> constructorMappings = resultMap.getConstructorResultMappings();
if (hasTypeHandlerForResultObject(rsw, resultType)) { // TypeHandler的处理,基本类型的处理
return createPrimitiveResultObject(rsw, resultMap, columnPrefix);
} else if (!constructorMappings.isEmpty()) { // 有参数的构造函数
return createParameterizedResultObject(rsw, resultType, constructorMappings, constructorArgTypes,
constructorArgs, columnPrefix);
} else if (resultType.isInterface() || metaType.hasDefaultConstructor()) {
return objectFactory.create(resultType); // 普通的Bean类型
} else if (shouldApplyAutomaticMappings(resultMap, false)) { // 自动映射
return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs, columnPrefix);
}
throw new ExecutorException("Do not know how to create an instance of " + resultType);
}
总结:ResultSetHandler是SqlSession四大对象中最困难的部分【似懂非懂,实则不懂,不懂又知】。ResultSetHandler用来对结果集进行处理,处理的结果分为嵌套对象【异常复杂且和缓存有关联】和普通对象【很复杂】的返回。通常情况下结果集的返回是普通对象,根据ResultMap和对象数据的映射关系,利用反射来获取结果,TypeHandler在此处使用来返回所需要的结果。