MyBatis SqlSession ResultHandler执行实现原理概述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lichunericli/article/details/82563648

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在此处使用来返回所需要的结果。

猜你喜欢

转载自blog.csdn.net/lichunericli/article/details/82563648