Mybatis源码学习(六)结果集自动封装机制

前言

上一章节我们已经追踪到mybatis的底层代码,是通过Statement进行数据库操作的.这一章再来学习查询出的数据是如何转换成我们自定义的实体.

1. ResultSetHandler源码

ResultSetHandler是一个接口, 定义了三个方法.

public interface ResultSetHandler {

  /**处理结果集
   * @param stmt              Statement
   * @param <E>               结果泛型
   * @return                  结果列表
   * @throws SQLException     异常
   */
  <E> List<E> handleResultSets(Statement stmt) throws SQLException;

  /**处理游标结果集
   * @param stmt                Statement
   * @param <E>                 结果泛型
   * @return                    游标结果集
   * @throws SQLException       异常
   */
  <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;

  /**处理输出参数
   * @param cs                  CallableStatement
   * @throws SQLException       异常
   */
  void handleOutputParameters(CallableStatement cs) throws SQLException;

}

2. DefaultResultSetHandler

作为ResultSetHandler的唯一实现,我们研究一下它是如何实现上述三个方法的吧.

public class DefaultResultSetHandler implements ResultSetHandler {

  private static final Object DEFERRED = new Object();

  /**
   * sql执行器
   */
  private final Executor executor;
  /**
   * 核心配置对象
   */
  private final Configuration configuration;
  /**
   * mappedStatement
   */
  private final MappedStatement mappedStatement;
  /**
   * 分页参数
   */
  private final RowBounds rowBounds;
  /**
   * 参数处理器
   */
  private final ParameterHandler parameterHandler;
  /**
   * 结果处理器
   */
  private final ResultHandler<?> resultHandler;
  /**
   * boundSql
   */
  private final BoundSql boundSql;
  /**
   * 类型处理器的注册器, 维护jdbcType和对应的处理器的关系
   */
  private final TypeHandlerRegistry typeHandlerRegistry;
  /**
   * 对象工厂
   */
  private final ObjectFactory objectFactory;
  /**
   * 反射工厂
   */
  private final ReflectorFactory reflectorFactory;

  // nested resultmaps
  /**
   *
   */
  private final Map<CacheKey, Object> nestedResultObjects = new HashMap<>();
  /**
   *
   */
  private final Map<String, Object> ancestorObjects = new HashMap<>();
  /**
   * 前一行的值
   */
  private Object previousRowValue;

  // multiple resultsets
  private final Map<String, ResultMapping> nextResultMaps = new HashMap<>();
  private final Map<CacheKey, List<PendingRelation>> pendingRelations = new HashMap<>();

  // Cached Automappings
  private final Map<String, List<UnMappedColumnAutoMapping>> autoMappingsCache = new HashMap<>();

  // temporary marking flag that indicate using constructor mapping (use field to reduce memory usage)
  private boolean useConstructorMappings;

  private static class PendingRelation {
    public MetaObject metaObject;
    public ResultMapping propertyMapping;
  }

  private static class UnMappedColumnAutoMapping {
    private final String column;
    private final String property;
    private final TypeHandler<?> typeHandler;
    private final boolean primitive;

    public UnMappedColumnAutoMapping(String column, String property, TypeHandler<?> typeHandler, boolean primitive) {
      this.column = column;
      this.property = property;
      this.typeHandler = typeHandler;
      this.primitive = primitive;
    }
  }

  /**构造函数
   * @param executor              sql执行器
   * @param mappedStatement       mappedStatement
   * @param parameterHandler      参数处理器
   * @param resultHandler         结果处理器
   * @param boundSql              boundSql
   * @param rowBounds             分页对象
   */
  public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler<?> resultHandler, BoundSql boundSql,
                                 RowBounds rowBounds) {
    //给类属性赋值
    this.executor = executor;
    this.configuration = mappedStatement.getConfiguration();
    this.mappedStatement = mappedStatement;
    this.rowBounds = rowBounds;
    this.parameterHandler = parameterHandler;
    this.boundSql = boundSql;
    this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
    this.objectFactory = configuration.getObjectFactory();
    this.reflectorFactory = configuration.getReflectorFactory();
    this.resultHandler = resultHandler;
  }

  //
  // HANDLE OUTPUT PARAMETER
  //

  /**处理输出参数
   * @param cs                  CallableStatement
   * @throws SQLException       异常
   */
  @Override
  public void handleOutputParameters(CallableStatement cs) throws SQLException {
    //获取参数对象
    final Object parameterObject = parameterHandler.getParameterObject();
    //构建参数对象的元数据对象
    final MetaObject metaParam = configuration.newMetaObject(parameterObject);
    //获取参数匹配关系
    final List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    for (int i = 0; i < parameterMappings.size(); i++) {
      final ParameterMapping parameterMapping = parameterMappings.get(i);
      if (parameterMapping.getMode() == ParameterMode.OUT || parameterMapping.getMode() == ParameterMode.INOUT) {
        //如果是输出类型的参数
        if (ResultSet.class.equals(parameterMapping.getJavaType())) {
          //如果<parameter>中指定的javaType为ResultSet
          //处理引用游标的输出参数
          handleRefCursorOutputParameter((ResultSet) cs.getObject(i + 1), parameterMapping, metaParam);
        } else {
          //获取参数的类型处理器
          final TypeHandler<?> typeHandler = parameterMapping.getTypeHandler();
          //利用参数对象的元数据对象进行代理,设置属性值
          metaParam.setValue(parameterMapping.getProperty(), typeHandler.getResult(cs, i + 1));
        }
      }
    }
  }

  /**处理引用游标的输出参数
   * @param rs                      结果集
   * @param parameterMapping        参数映射关系
   * @param metaParam               参数对象的元数据对象
   * @throws SQLException           异常
   */
  private void handleRefCursorOutputParameter(ResultSet rs, ParameterMapping parameterMapping, MetaObject metaParam) throws SQLException {
    if (rs == null) {
      return;
    }
    try {
      //获取resultMapId
      final String resultMapId = parameterMapping.getResultMapId();
      //根据id获取ResultMap
      final ResultMap resultMap = configuration.getResultMap(resultMapId);
      //构造结果集包装器
      final ResultSetWrapper rsw = new ResultSetWrapper(rs, configuration);
      if (this.resultHandler == null) {
        //如果结果处理器为空,创建一个默认的结果处理器
        final DefaultResultHandler resultHandler = new DefaultResultHandler(objectFactory);
        //处理行数据值
        handleRowValues(rsw, resultMap, resultHandler, new RowBounds(), null);
        //给参数设置值
        metaParam.setValue(parameterMapping.getProperty(), resultHandler.getResultList());
      } else {
        //处理行数据值
        handleRowValues(rsw, resultMap, resultHandler, new RowBounds(), null);
        //因为指定了结果处理器,不会设置参数的值
      }
    } finally {
      // issue #228 (close resultsets)
      //关闭结果集
      closeResultSet(rs);
    }
  }

  /**处理结果集
   * @param stmt              Statement
   * @return                  结果列表
   * @throws SQLException     异常
   */
  //
  // HANDLE RESULT SETS
  //
  @Override
  public List<Object> handleResultSets(Statement stmt) throws SQLException {
    ErrorContext.instance().activity("handling results").object(mappedStatement.getId());

    //初始化多结果的结果列表
    final List<Object> multipleResults = new ArrayList<>();

    int resultSetCount = 0;
    //获取第一个结果集的包装器
    ResultSetWrapper rsw = getFirstResultSet(stmt);
    //从mappedStatement中获取多结果的映射关系
    List<ResultMap> resultMaps = mappedStatement.getResultMaps();
    int resultMapCount = resultMaps.size();
    //验证结果映射的count
    validateResultMapsCount(rsw, resultMapCount);
    while (rsw != null && resultMapCount > resultSetCount) {
      //有结果集,并且结果集映射的数量大于结果集的count时,循环处理每个结果期

      //获取当前结果集的映射关系
      ResultMap resultMap = resultMaps.get(resultSetCount);
      //处理当前结果集
      handleResultSet(rsw, resultMap, multipleResults, null);
      //获取下一个结果集
      rsw = getNextResultSet(stmt);
      //处理完结果集后清除nestedResultObjects中数据
      cleanUpAfterHandlingResultSet();
      //索引++
      resultSetCount++;
    }

    String[] resultSets = mappedStatement.getResultSets();
    if (resultSets != null) {
      while (rsw != null && resultSetCount < resultSets.length) {
        ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
        if (parentMapping != null) {
          String nestedResultMapId = parentMapping.getNestedResultMapId();
          ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
          handleResultSet(rsw, resultMap, null, parentMapping);
        }
        rsw = getNextResultSet(stmt);
        cleanUpAfterHandlingResultSet();
        resultSetCount++;
      }
    }

    //如果只有一个结果集,返回列表中第一个元素, 否则返回整个结果集列表
    return collapseSingleResultList(multipleResults);
  }

  /**处理游标结果集
   * @param stmt                Statement
   * @param <E>                 结果泛型
   * @return                    游标结果集
   * @throws SQLException       异常
   */
  @Override
  public <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException {
    ErrorContext.instance().activity("handling cursor results").object(mappedStatement.getId());

    //获取第一个结果集的包装器
    ResultSetWrapper rsw = getFirstResultSet(stmt);

    //从mappedStatement中获取结果的映射关系
    List<ResultMap> resultMaps = mappedStatement.getResultMaps();

    int resultMapCount = resultMaps.size();
    //验证结果映射的count
    validateResultMapsCount(rsw, resultMapCount);
    if (resultMapCount != 1) {
      //游标类型的查询不支持映射多个resultMap
      throw new ExecutorException("Cursor results cannot be mapped to multiple resultMaps");
    }

    ResultMap resultMap = resultMaps.get(0);
    //返回一个默认游标
    return new DefaultCursor<>(this, resultMap, rsw, rowBounds);
  }

  /**获取第一个结果集
   * @param stmt            Statement
   * @return                结果集包装器
   * @throws SQLException   异常
   */
  private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException {
    //从statement中获取一次结果集
    ResultSet rs = stmt.getResultSet();
    while (rs == null) {
      // move forward to get the first resultset in case the driver
      // doesn't return the resultset as the first result (HSQLDB 2.1)
      if (stmt.getMoreResults()) {
        //如果有结果
        //再执行一次获取结果集
        rs = stmt.getResultSet();
      } else {
        if (stmt.getUpdateCount() == -1) {
          //如果已经没有结果,break
          // no more results. Must be no resultset
          break;
        }
      }
    }
    //结果集不为空时,返回结果集的包装器,否则返回null
    return rs != null ? new ResultSetWrapper(rs, configuration) : null;
  }

  /**获取下一个结果集
   * @param stmt      Statement
   * @return          结果集包装器
   */
  private ResultSetWrapper getNextResultSet(Statement stmt) {
    // Making this method tolerant of bad JDBC drivers
    try {
      if (stmt.getConnection().getMetaData().supportsMultipleResultSets()) {
        //如果连接支持多结果集
        // Crazy Standard JDBC way of determining if there are more results
        if (!(!stmt.getMoreResults() && stmt.getUpdateCount() == -1)) {
          //只有有结果,或者更新条数不为-1,就获取一次结果集
          ResultSet rs = stmt.getResultSet();
          if (rs == null) {
            //为空时递归获取
            return getNextResultSet(stmt);
          } else {
            //不为空时返回包装器
            return new ResultSetWrapper(rs, configuration);
          }
        }
      }
    } catch (Exception e) {
      // Intentionally ignored.
    }
    return null;
  }

  /**关闭结果集
   * @param rs
   */
  private void closeResultSet(ResultSet rs) {
    try {
      if (rs != null) {
        rs.close();
      }
    } catch (SQLException e) {
      // ignore
    }
  }

  /**
   * 清除层级对象的缓存
   */
  private void cleanUpAfterHandlingResultSet() {
    nestedResultObjects.clear();
  }

  /**验证结果映射的数量
   * @param rsw               结果集包装器
   * @param resultMapCount    结果映射的数量
   */
  private void validateResultMapsCount(ResultSetWrapper rsw, int resultMapCount) {
    //有结果的时候,结果映射的数量不能小于1
    if (rsw != null && resultMapCount < 1) {
      throw new ExecutorException("A query was run and no Result Maps were found for the Mapped Statement '" + mappedStatement.getId()
          + "'.  It's likely that neither a Result Type nor a Result Map was specified.");
    }
  }

  /**处理结果集
   * @param rsw                   结果集包装器
   * @param resultMap             结果映射关系
   * @param multipleResults       最终的结果列表对象
   * @param parentMapping         父级结果映射关系
   * @throws SQLException         异常
   */
  private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
    try {
      if (parentMapping != null) {
        //处理行数据值
        handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
      } else {
        if (resultHandler == null) {
          //构造默认的结果处理器
          DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
          //处理行数据值
          handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
          //处理后的结果加入到最终的结果列表中
          multipleResults.add(defaultResultHandler.getResultList());
        } else {
          //处理行数据值
          handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
        }
      }
    } finally {
      // issue #228 (close resultsets)
      //关闭结果集
      closeResultSet(rsw.getResultSet());
    }
  }

  /**将结果转化成单个结果集的形式
   * @param multipleResults       多结果集的结果列表
   * @return                      结果列表
   */
  @SuppressWarnings("unchecked")
  private List<Object> collapseSingleResultList(List<Object> multipleResults) {
    //如果列表数量是1, 取第一个结果列表返回, 否则返回原始结果列表
    return multipleResults.size() == 1 ? (List<Object>) multipleResults.get(0) : multipleResults;
  }

  //
  // HANDLE ROWS FOR SIMPLE RESULTMAP
  //

  /**处理每行数据,封装到resultMap
   * @param rsw               结果集包装器
   * @param resultMap         结果映射关系
   * @param resultHandler     结果处理器
   * @param rowBounds         分页对象
   * @param parentMapping     父结果映射关系
   * @throws SQLException     异常
   */
  public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
    if (resultMap.hasNestedResultMaps()) {
      //如果是嵌套层级的resultMap, 例如association或collection中指定了resultMap
      //检查分页
      ensureNoRowBounds();
      //检查结果处理器
      checkResultHandler();
      //处理嵌套层级的行数据
      handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
    } else {
      //处理非嵌套层级的行数据
      handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
    }
  }

  /**
   * 检查分页参数
   */
  private void ensureNoRowBounds() {
    //如果开启了分页安全检查
    //limit需要小于最大的limit
    //offset需要大于0
    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.");
    }
  }

  /**
   * 检查结果处理器
   */
  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.");
    }
  }

  /**处理非嵌套层级的行数据
   * @param rsw               结果集包装器
   * @param resultMap         结果映射关系
   * @param resultHandler     结果处理器
   * @param rowBounds         分页对象
   * @param parentMapping     父结果映射关系
   * @throws SQLException     异常
   */
  private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
      throws SQLException {
    //构建一个默认的结果上线文对象
    DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
    ResultSet resultSet = rsw.getResultSet();
    //根据分页参数跳转到对应的行, 采取的是内存分页的方式
    skipRows(resultSet, rowBounds);
    while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
      //有数据可以处理时

      //解析鉴别器指定的resultMap
      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
      //取出行值映射到结果对象中
      Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
      //存储对象
      storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
    }
  }

  /**存储对象
   * @param resultHandler       结果处理器
   * @param resultContext       结果上线文对象
   * @param rowValue            实际的结果值
   * @param parentMapping       父结果映射关系
   * @param rs                  结果集
   * @throws SQLException       异常
   */
  private void storeObject(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue, ResultMapping parentMapping, ResultSet rs) throws SQLException {
    if (parentMapping != null) {
      //将值设置到父级对象中
      linkToParents(rs, parentMapping, rowValue);
    } else {
      //调用结果处理器处理数据
      callResultHandler(resultHandler, resultContext, rowValue);
    }
  }

  /**调用结果处理器处理数据
   * @param resultHandler       结果处理器
   * @param resultContext       结果上线文对象
   * @param rowValue            实际的结果值
   */
  @SuppressWarnings("unchecked" /* because ResultHandler<?> is always ResultHandler<Object>*/)
  private void callResultHandler(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue) {
    //将数据放入上下文对象
    resultContext.nextResultObject(rowValue);
    //调用结果处理器处理结果
    ((ResultHandler<Object>) resultHandler).handleResult(resultContext);
  }

  /**判断是否需要处理更多行数据
   * @param context           结果上线文对象
   * @param rowBounds         分页对象
   * @return
   */
  private boolean shouldProcessMoreRows(ResultContext<?> context, RowBounds rowBounds) {
    //结果上下文对象没有停止,并且结果数小于分页的limit
    return !context.isStopped() && context.getResultCount() < rowBounds.getLimit();
  }

  /**跳过分页的行
   * @param rs                结果集
   * @param rowBounds         分页参数
   * @throws SQLException     异常
   */
  private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {
    if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
      //如果结果集类型不是只能前向移动的类型
      if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {
        //将游标跳转到offset的位置
        rs.absolute(rowBounds.getOffset());
      }
    } else {
      //将游标跳转到offset的位置
      for (int i = 0; i < rowBounds.getOffset(); i++) {
        if (!rs.next()) {
          break;
        }
      }
    }
  }

  //
  // GET VALUE FROM ROW FOR SIMPLE RESULT MAP
  //

  /**获取行值
   * @param rsw             结果集包装器
   * @param resultMap       结果映射关系
   * @param columnPrefix    列名前缀
   * @return                resultMap中指定类的对象
   * @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, resultMap.getType())) {
      //如果对象不为空, 并且该对象没有类型处理器
      //构建一个返回值对象的元数据对象
      final MetaObject metaObject = configuration.newMetaObject(rowValue);
      //是否找到对象值标志
      boolean foundValues = this.useConstructorMappings;
      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, 否则返回null
      rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
    }
    return rowValue;
  }

  //
  // GET VALUE FROM ROW FOR NESTED RESULT MAP
  //

  /**获取行值
   * @param rsw                 结果集包装器
   * @param resultMap           结果映射关系
   * @param combinedKey         每一行数据生成的缓存key
   * @param columnPrefix        列名前缀
   * @param partialObject       部分对象
   * @return                    resultMap中指定类的对象
   * @throws SQLException       异常
   */
  private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, String columnPrefix, Object partialObject) throws SQLException {
    final String resultMapId = resultMap.getId();
    Object rowValue = partialObject;
    if (rowValue != null) {
      //创建一个值对象的元数据对象
      final MetaObject metaObject = configuration.newMetaObject(rowValue);
      //将值和resultMapId存放在map中
      putAncestor(rowValue, resultMapId);
      //处理嵌套层级的resultMapping,可能存在循环引用自身对象的情况,所以将rowValue先放入缓存
      applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);
      //从缓存map中移除元素
      ancestorObjects.remove(resultMapId);
    } else {
      //创建一个懒加载对象,用于加载属性
      final ResultLoaderMap lazyLoader = new ResultLoaderMap();
      //创建结果对象
      //将拦截载属性加入到懒加载对象中
      //为包含嵌套查询的结果对象创建代理对象
      rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
      if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
        //为数据创建元数据对象
        final MetaObject metaObject = configuration.newMetaObject(rowValue);
        boolean foundValues = this.useConstructorMappings;
        if (shouldApplyAutomaticMappings(resultMap, true)) {
          //应用自动映射
          foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
        }
        //引用属性映射
        foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
        //将值和resultMapId存放在map中
        putAncestor(rowValue, resultMapId);
        //处理嵌套层级的resultMapping,可能存在循环引用自身对象的情况,所以将rowValue先放入缓存
        foundValues = applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;
        //从缓存map中移除元素
        ancestorObjects.remove(resultMapId);
        //如果懒加载对象中有拦截属性,设置有值标志为找到值
        foundValues = lazyLoader.size() > 0 || foundValues;
        //如果找到值或者配置空指定了即使没数据返回空对象,返回值对象rowValue, 否则返回null
        rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
      }
      if (combinedKey != CacheKey.NULL_CACHE_KEY) {
        nestedResultObjects.put(combinedKey, rowValue);
      }
    }
    return rowValue;
  }

  /**将键值对放入map
   * @param resultObject        结果对象
   * @param resultMapId         resultMapId
   */
  private void putAncestor(Object resultObject, String resultMapId) {
    ancestorObjects.put(resultMapId, resultObject);
  }

  /**是否自动映射
   * @param resultMap           ResultMap
   * @param isNested            是否是嵌套层级
   * @return                    是否自动映射
   */
  private boolean shouldApplyAutomaticMappings(ResultMap resultMap, boolean isNested) {
    if (resultMap.getAutoMapping() != null) {
      //如果配置了自动映射属性,直接返回
      return resultMap.getAutoMapping();
    } else {
      if (isNested) {
        //如果是嵌套层级并且是全匹配,返回自动映射
        return AutoMappingBehavior.FULL == configuration.getAutoMappingBehavior();
      } else {
        //如果是非嵌套层级,只要不是不自动匹配, 返回自动映射
        return AutoMappingBehavior.NONE != configuration.getAutoMappingBehavior();
      }
    }
  }

  //
  // PROPERTY MAPPINGS
  //

  /**根据属性匹配,设置属性值
   * @param rsw                 结果集包装器
   * @param resultMap           结果映射关系
   * @param metaObject          元数据
   * @param lazyLoader          懒加载器
   * @param columnPrefix        列名前缀
   * @return                    对象是否赋值
   * @throws SQLException       异常
   */
  private boolean applyPropertyMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, ResultLoaderMap lazyLoader, String columnPrefix)
      throws SQLException {
    //获取列名
    final List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
    boolean foundValues = false;
    //获取属性值的映射关系
    final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();
    for (ResultMapping propertyMapping : propertyMappings) {
      //属性名加上列名前缀
      String column = prependPrefix(propertyMapping.getColumn(), columnPrefix);
      if (propertyMapping.getNestedResultMapId() != null) {
        // the user added a column attribute to a nested result map, ignore it
        column = null;
      }
      if (propertyMapping.isCompositeResult()
          || (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH)))
          || propertyMapping.getResultSet() != null) {
        //获取属性的值
        Object value = getPropertyMappingValue(rsw.getResultSet(), metaObject, propertyMapping, lazyLoader, columnPrefix);
        // issue #541 make property optional
        final String property = propertyMapping.getProperty();
        if (property == null) {
          continue;
        } else if (value == DEFERRED) {
          //如果是懒加载,认为该属性有值
          foundValues = true;
          continue;
        }
        if (value != null) {
          //值不为空,认为属性有值
          foundValues = true;
        }
        if (value != null || (configuration.isCallSettersOnNulls() && !metaObject.getSetterType(property).isPrimitive())) {
          // gcode issue #377, call setter on nulls (value is not 'found')
          //给对象设置值
          metaObject.setValue(property, value);
        }
      }
    }
    return foundValues;
  }

  /**获取属性的映射值
   * @param rs                    结果集
   * @param metaResultObject      元数据对象
   * @param propertyMapping       属性映射关系
   * @param lazyLoader            懒加载集
   * @param columnPrefix          列名前缀
   * @return                      属性值
   * @throws SQLException         异常
   */
  private Object getPropertyMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix)
      throws SQLException {
    if (propertyMapping.getNestedQueryId() != null) {
      //获取嵌套查询结果
      return getNestedQueryMappingValue(rs, metaResultObject, propertyMapping, lazyLoader, columnPrefix);
    } else if (propertyMapping.getResultSet() != null) {
      //
      addPendingChildRelation(rs, metaResultObject, propertyMapping);   // TODO is that OK?
      return DEFERRED;
    } else {
      //获取类型处理器
      final TypeHandler<?> typeHandler = propertyMapping.getTypeHandler();
      //列名拼上前缀
      final String column = prependPrefix(propertyMapping.getColumn(), columnPrefix);
      //获取值
      return typeHandler.getResult(rs, column);
    }
  }

  /**创建自动映射的关系
   * @param rsw                 结果集包装器
   * @param resultMap           对象关系映射
   * @param metaObject          元数据对象
   * @param columnPrefix        列前缀
   * @return                    属性映射的关系列表
   * @throws SQLException       异常
   */
  private List<UnMappedColumnAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
    final String mapKey = resultMap.getId() + ":" + columnPrefix;
    //缓存汇总获取映射关系
    List<UnMappedColumnAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
    if (autoMapping == null) {
      autoMapping = new ArrayList<>();
      //获取未匹配的列
      final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
      for (String columnName : unmappedColumnNames) {
        //遍历未匹配的列名
        //根据列名处理成属性名, 有前缀,去掉前缀
        String propertyName = columnName;
        if (columnPrefix != null && !columnPrefix.isEmpty()) {
          // When columnPrefix is specified,
          // ignore columns without the prefix.
          if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
            propertyName = columnName.substring(columnPrefix.length());
          } else {
            continue;
          }
        }
        //元数据对象中查找是否有对应的属性
        final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
        if (property != null && metaObject.hasSetter(property)) {
          if (resultMap.getMappedProperties().contains(property)) {
            //该属性已经匹配过,忽略
            continue;
          }
          //获取属性的类型
          final Class<?> propertyType = metaObject.getSetterType(property);
          if (typeHandlerRegistry.hasTypeHandler(propertyType, rsw.getJdbcType(columnName))) {
            //获取类型处理器
            final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
            //把当前自动映射关系加入到集合
            autoMapping.add(new UnMappedColumnAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
          } else {
            configuration.getAutoMappingUnknownColumnBehavior()
                .doAction(mappedStatement, columnName, property, propertyType);
          }
        } else {
          configuration.getAutoMappingUnknownColumnBehavior()
              .doAction(mappedStatement, columnName, (property != null) ? property : propertyName, null);
        }
      }
      //映射关系放入缓存
      autoMappingsCache.put(mapKey, autoMapping);
    }
    //返回自动匹配的关系列表
    return autoMapping;
  }

  /**是否自动映射
   * @param rsw                 结果集包装器
   * @param resultMap           对象关系映射
   * @param metaObject          元数据对象
   * @param columnPrefix        列前缀
   * @return                    是否自动映射
   * @throws SQLException       异常
   */
  private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
    //对未匹配列进行自动映射
    List<UnMappedColumnAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
    boolean foundValues = false;
    if (!autoMapping.isEmpty()) {
      for (UnMappedColumnAutoMapping mapping : autoMapping) {
        //使用类型处理器获取值
        final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
        if (value != null) {
          foundValues = true;
        }
        if (value != null || (configuration.isCallSettersOnNulls() && !mapping.primitive)) {
          // gcode issue #377, call setter on nulls (value is not 'found')
          //设置值
          metaObject.setValue(mapping.property, value);
        }
      }
    }
    return foundValues;
  }

  // MULTIPLE RESULT SETS

  /**将值设置到父级对象中
   * @param rs                结果集
   * @param parentMapping     父级属性映射关系
   * @param rowValue          值
   * @throws SQLException     异常
   */
  private void linkToParents(ResultSet rs, ResultMapping parentMapping, Object rowValue) throws SQLException {
    //计算缓存key
    CacheKey parentKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(), parentMapping.getForeignColumn());
    List<PendingRelation> parents = pendingRelations.get(parentKey);
    if (parents != null) {
      for (PendingRelation parent : parents) {
        if (parent != null && rowValue != null) {
          //将值设置到resultMap的collection或者association中
          linkObjects(parent.metaObject, parent.propertyMapping, rowValue);
        }
      }
    }
  }

  /**
   * @param rs
   * @param metaResultObject
   * @param parentMapping
   * @throws SQLException
   */
  private void addPendingChildRelation(ResultSet rs, MetaObject metaResultObject, ResultMapping parentMapping) throws SQLException {
    //计算缓存key
    CacheKey cacheKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(), parentMapping.getColumn());
    PendingRelation deferLoad = new PendingRelation();
    deferLoad.metaObject = metaResultObject;
    deferLoad.propertyMapping = parentMapping;
    List<PendingRelation> relations = pendingRelations.computeIfAbsent(cacheKey, k -> new ArrayList<>());
    // issue #255
    relations.add(deferLoad);
    ResultMapping previous = nextResultMaps.get(parentMapping.getResultSet());
    if (previous == null) {
      nextResultMaps.put(parentMapping.getResultSet(), parentMapping);
    } else {
      if (!previous.equals(parentMapping)) {
        throw new ExecutorException("Two different properties are mapped to the same resultSet");
      }
    }
  }

  /**为多结果创建缓存key
   * @param rs                    结果集
   * @param resultMapping         属性关系映射
   * @param names                 属性名
   * @param columns               列名
   * @return                      缓存key
   * @throws SQLException         异常
   */
  private CacheKey createKeyForMultipleResults(ResultSet rs, ResultMapping resultMapping, String names, String columns) throws SQLException {
    CacheKey cacheKey = new CacheKey();
    //使用resultMapping对象计算缓存key
    cacheKey.update(resultMapping);
    if (columns != null && names != null) {
      String[] columnsArray = columns.split(",");
      String[] namesArray = names.split(",");
      for (int i = 0; i < columnsArray.length; i++) {
        Object value = rs.getString(columnsArray[i]);
        if (value != null) {
          //使用属性和值计算缓存key
          cacheKey.update(namesArray[i]);
          cacheKey.update(value);
        }
      }
    }
    return cacheKey;
  }

  //
  // INSTANTIATION & CONSTRUCTOR MAPPING
  //

  /**创建结果对象
   * @param rsw                   结果集包装器
   * @param resultMap             对象关系映射
   * @param lazyLoader            懒加载器
   * @param columnPrefix          列名前缀
   * @return                      结果对象
   * @throws SQLException         异常
   */
  private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException {
    this.useConstructorMappings = false; // reset previous mapping result
    final List<Class<?>> constructorArgTypes = new ArrayList<>();
    final List<Object> constructorArgs = new ArrayList<>();
    //创建结果对象
    Object resultObject = createResultObject(rsw, resultMap, constructorArgTypes, constructorArgs, columnPrefix);
    if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
      final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();
      for (ResultMapping propertyMapping : propertyMappings) {
        //遍历属性映射关系
        // issue gcode #109 && issue #149
        if (propertyMapping.getNestedQueryId() != null && propertyMapping.isLazy()) {
          //如果是嵌套查询,并且是懒加载
          //为结果对象创建代理对象
          resultObject = configuration.getProxyFactory().createProxy(resultObject, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
          break;
        }
      }
    }
    this.useConstructorMappings = resultObject != null && !constructorArgTypes.isEmpty(); // set current mapping result
    return resultObject;
  }

  /**创建结果对象
   * @param rsw                   结果集包装器
   * @param resultMap             对象关系映射
   * @param constructorArgTypes   构造函数参数类型列表
   * @param constructorArgs       构造函数参数
   * @param columnPrefix          列名前缀
   * @return                      结果对象
   * @throws SQLException         异常
   */
  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)) {
      //如果有结果类型有类处理器
      //创建原始的结果数据对象
      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);
    } else if (shouldApplyAutomaticMappings(resultMap, false)) {
      //如果需要自动匹配
      //根据构造函数创建结果对象
      return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs);
    }
    throw new ExecutorException("Do not know how to create an instance of " + resultType);
  }

  /**创建参数化的结果对象
   * @param rsw                   结果集包装器
   * @param resultType            结果类型
   * @param constructorMappings   构造函数的映射关系
   * @param constructorArgTypes   构造函数参数类型列表
   * @param constructorArgs       构造函数参数
   * @param columnPrefix          列名前缀
   * @return                      结果对象
   */
  Object createParameterizedResultObject(ResultSetWrapper rsw, Class<?> resultType, List<ResultMapping> constructorMappings,
                                         List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix) {
    boolean foundValues = false;
    for (ResultMapping constructorMapping : constructorMappings) {
      //遍历构造函数的匹配关系
      //获取java类型
      final Class<?> parameterType = constructorMapping.getJavaType();
      //获取列名
      final String column = constructorMapping.getColumn();
      final Object value;
      try {
        if (constructorMapping.getNestedQueryId() != null) {
          //如果指定了嵌套查询
          //获取嵌套查询的构造函数的值
          value = getNestedQueryConstructorValue(rsw.getResultSet(), constructorMapping, columnPrefix);
        } else if (constructorMapping.getNestedResultMapId() != null) {
          //如果是嵌套的resultMap
          final ResultMap resultMap = configuration.getResultMap(constructorMapping.getNestedResultMapId());
          //获取结果值
          value = getRowValue(rsw, resultMap, getColumnPrefix(columnPrefix, constructorMapping));
        } else {
          final TypeHandler<?> typeHandler = constructorMapping.getTypeHandler();
          //根据类型处理器获取值
          value = typeHandler.getResult(rsw.getResultSet(), prependPrefix(column, columnPrefix));
        }
      } catch (ResultMapException | SQLException e) {
        throw new ExecutorException("Could not process result for mapping: " + constructorMapping, e);
      }
      constructorArgTypes.add(parameterType);
      constructorArgs.add(value);
      //设置找到对应的值标记
      foundValues = value != null || foundValues;
    }
    //根据构造函数创建对象
    return foundValues ? objectFactory.create(resultType, constructorArgTypes, constructorArgs) : null;
  }

  /**使用构造函数创建对象
   * @param rsw                   结果集包装器
   * @param resultType            结果类型
   * @param constructorArgTypes   构造函数参数类型列表
   * @param constructorArgs       构造函数参数
   * @return                      结果对象
   * @throws SQLException         异常
   */
  private Object createByConstructorSignature(ResultSetWrapper rsw, Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) throws SQLException {
    //获取构造函数列表
    final Constructor<?>[] constructors = resultType.getDeclaredConstructors();
    //找到默认的构造函数
    final Constructor<?> defaultConstructor = findDefaultConstructor(constructors);
    if (defaultConstructor != null) {
      //使用默认构造函数创建对象
      return createUsingConstructor(rsw, resultType, constructorArgTypes, constructorArgs, defaultConstructor);
    } else {
      for (Constructor<?> constructor : constructors) {
        if (allowedConstructorUsingTypeHandlers(constructor, rsw.getJdbcTypes())) {
          //遍历构造函数,用可以使用类型处理器的构造函数,创建对象
          return createUsingConstructor(rsw, resultType, constructorArgTypes, constructorArgs, constructor);
        }
      }
    }
    throw new ExecutorException("No constructor found in " + resultType.getName() + " matching " + rsw.getClassNames());
  }

  /**使用构造函数创建对象
   * @param rsw                   结果集包装器
   * @param resultType            结果类型
   * @param constructorArgTypes   构造函数参数类型列表
   * @param constructorArgs       构造函数参数
   * @param constructor           构造函数
   * @return                      结果对象
   * @throws SQLException         异常
   */
  private Object createUsingConstructor(ResultSetWrapper rsw, Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, Constructor<?> constructor) throws SQLException {
    boolean foundValues = false;
    for (int i = 0; i < constructor.getParameterTypes().length; i++) {
      //遍历构造函数的参数类型
      //获取参数类型
      Class<?> parameterType = constructor.getParameterTypes()[i];
      //获取列名
      String columnName = rsw.getColumnNames().get(i);
      //获取类型处理器
      TypeHandler<?> typeHandler = rsw.getTypeHandler(parameterType, columnName);
      //获取属性值
      Object value = typeHandler.getResult(rsw.getResultSet(), columnName);
      constructorArgTypes.add(parameterType);
      constructorArgs.add(value);
      //设置找到对应的值标记
      foundValues = value != null || foundValues;
    }
    //使用构造函数创建结果对象
    return foundValues ? objectFactory.create(resultType, constructorArgTypes, constructorArgs) : null;
  }

  /**查找默认的构造函数
   * @param constructors      构造函数类列表
   * @return                  默认的构造函数
   */
  private Constructor<?> findDefaultConstructor(final Constructor<?>[] constructors) {
    if (constructors.length == 1) {
      //只有一个构造函数时,返会唯一的构造函数
      return constructors[0];
    }

    for (final Constructor<?> constructor : constructors) {
      if (constructor.isAnnotationPresent(AutomapConstructor.class)) {
        //返回被自动匹配注解标记的构造函数
        return constructor;
      }
    }
    //返回空
    return null;
  }

  /**是否允许构造函数使用类型处理器
   * @param constructor         构造函数对象
   * @param jdbcTypes           结果对象的所有属性的jdbc类型
   * @return                    是否允许构造函数使用类型处理器
   */
  private boolean allowedConstructorUsingTypeHandlers(final Constructor<?> constructor, final List<JdbcType> jdbcTypes) {
    //获取构造函数的参数类型
    final Class<?>[] parameterTypes = constructor.getParameterTypes();
    if (parameterTypes.length != jdbcTypes.size()) {
      return false;
    }
    for (int i = 0; i < parameterTypes.length; i++) {
      if (!typeHandlerRegistry.hasTypeHandler(parameterTypes[i], jdbcTypes.get(i))) {
        //如果没有改java类型和jdbc类型对应的类处理器
        //返回false
        return false;
      }
    }
    return true;
  }

  /**创建原始的结果数据对象
   * @param rsw               结果集包装器
   * @param resultMap         对象关系映射
   * @param columnPrefix      列名前缀
   * @return                  结果对象
   * @throws SQLException     异常
   */
  private Object createPrimitiveResultObject(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException {
    //获取resultMap的java类型
    final Class<?> resultType = resultMap.getType();
    final String columnName;
    if (!resultMap.getResultMappings().isEmpty()) {
      //如果配置了属性的映射关系
      final List<ResultMapping> resultMappingList = resultMap.getResultMappings();
      final ResultMapping mapping = resultMappingList.get(0);
      //获取列名
      columnName = prependPrefix(mapping.getColumn(), columnPrefix);
    } else {
      //否则取第一列列名
      columnName = rsw.getColumnNames().get(0);
    }
    //获取类型处理器
    final TypeHandler<?> typeHandler = rsw.getTypeHandler(resultType, columnName);
    //获取该列的结果值
    return typeHandler.getResult(rsw.getResultSet(), columnName);
  }

  //
  // NESTED QUERY
  //

  /**获取嵌套查询的值
   * @param rs                    结果集
   * @param constructorMapping    构造函数的映射
   * @param columnPrefix          列名前缀
   * @return                      结果值
   * @throws SQLException         异常
   */
  private Object getNestedQueryConstructorValue(ResultSet rs, ResultMapping constructorMapping, String columnPrefix) throws SQLException {
    //获取嵌套查询id
    final String nestedQueryId = constructorMapping.getNestedQueryId();
    //获取嵌套查询的语句对象
    final MappedStatement nestedQuery = configuration.getMappedStatement(nestedQueryId);
    //嵌套查询的参数类型
    final Class<?> nestedQueryParameterType = nestedQuery.getParameterMap().getType();
    //构建嵌套查询的参数对象
    final Object nestedQueryParameterObject = prepareParameterForNestedQuery(rs, constructorMapping, nestedQueryParameterType, columnPrefix);
    Object value = null;
    if (nestedQueryParameterObject != null) {
      //如果参数对象不为空
      //获取语句
      final BoundSql nestedBoundSql = nestedQuery.getBoundSql(nestedQueryParameterObject);
      //生成缓存key
      final CacheKey key = executor.createCacheKey(nestedQuery, nestedQueryParameterObject, RowBounds.DEFAULT, nestedBoundSql);
      //获取构造函数的类型
      final Class<?> targetType = constructorMapping.getJavaType();
      //构建结果加载器
      final ResultLoader resultLoader = new ResultLoader(configuration, executor, nestedQuery, nestedQueryParameterObject, targetType, key, nestedBoundSql);
      //加载结果
      value = resultLoader.loadResult();
    }
    return value;
  }

  /**获取嵌套查询的值
   * @param rs                  结果集
   * @param metaResultObject    结果的元数据对象
   * @param propertyMapping     属性映射对象
   * @param lazyLoader          懒加载
   * @param columnPrefix        列名前缀
   * @return                    结果值
   * @throws SQLException       异常
   */
  private Object getNestedQueryMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix)
      throws SQLException {
    //获取嵌套查询id
    final String nestedQueryId = propertyMapping.getNestedQueryId();
    //获取属性名
    final String property = propertyMapping.getProperty();
    //获取嵌套查询的语句对象
    final MappedStatement nestedQuery = configuration.getMappedStatement(nestedQueryId);
    //嵌套查询的参数类型
    final Class<?> nestedQueryParameterType = nestedQuery.getParameterMap().getType();
    //构建嵌套查询的参数对象
    final Object nestedQueryParameterObject = prepareParameterForNestedQuery(rs, propertyMapping, nestedQueryParameterType, columnPrefix);
    Object value = null;
    if (nestedQueryParameterObject != null) {
      //如果有参数
      final BoundSql nestedBoundSql = nestedQuery.getBoundSql(nestedQueryParameterObject);
      final CacheKey key = executor.createCacheKey(nestedQuery, nestedQueryParameterObject, RowBounds.DEFAULT, nestedBoundSql);
      final Class<?> targetType = propertyMapping.getJavaType();
      if (executor.isCached(nestedQuery, key)) {
        //缓存中有数据
        //调用延迟加载
        executor.deferLoad(nestedQuery, metaResultObject, property, key, targetType);
        value = DEFERRED;
      } else {
        //构建一个ResultLoader
        final ResultLoader resultLoader = new ResultLoader(configuration, executor, nestedQuery, nestedQueryParameterObject, targetType, key, nestedBoundSql);
        if (propertyMapping.isLazy()) {
          //如果是懒加载,把当前结果的加载器加入到懒加载中
          lazyLoader.addLoader(property, metaResultObject, resultLoader);
          value = DEFERRED;
        } else {
          //直接加载对象值
          value = resultLoader.loadResult();
        }
      }
    }
    return value;
  }

  /**为嵌套查询准备餐宿
   * @param rs                结果集
   * @param resultMapping     属性映射关系对象
   * @param parameterType     参数类型
   * @param columnPrefix      列名前缀
   * @return                  参数对象
   * @throws SQLException     异常
   */
  private Object prepareParameterForNestedQuery(ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException {
    if (resultMapping.isCompositeResult()) {
      //多参数的嵌套查询
      return prepareCompositeKeyParameter(rs, resultMapping, parameterType, columnPrefix);
    } else {
      //单个参数的嵌套查询
      return prepareSimpleKeyParameter(rs, resultMapping, parameterType, columnPrefix);
    }
  }

  /**准备单个参数的参数对象
   * @param rs                结果集
   * @param resultMapping     属性映射关系对象
   * @param parameterType     参数类型
   * @param columnPrefix      列名前缀
   * @return                  参数对象
   * @throws SQLException     异常
   */
  private Object prepareSimpleKeyParameter(ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException {
    final TypeHandler<?> typeHandler;
    if (typeHandlerRegistry.hasTypeHandler(parameterType)) {
      //获取参数类型的处理器
      typeHandler = typeHandlerRegistry.getTypeHandler(parameterType);
    } else {
      //设置为未知类型的类型处理器
      typeHandler = typeHandlerRegistry.getUnknownTypeHandler();
    }
    //获取结果
    return typeHandler.getResult(rs, prependPrefix(resultMapping.getColumn(), columnPrefix));
  }

  /**准备多参数的参数对象
   * @param rs                结果集
   * @param resultMapping     属性映射关系对象
   * @param parameterType     参数类型
   * @param columnPrefix      列名前缀
   * @return                  参数对象
   * @throws SQLException     异常
   */
  private Object prepareCompositeKeyParameter(ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException {
    //实例化参数对象
    final Object parameterObject = instantiateParameterObject(parameterType);
    //获取参数对象的元数据对象
    final MetaObject metaObject = configuration.newMetaObject(parameterObject);
    boolean foundValues = false;
    for (ResultMapping innerResultMapping : resultMapping.getComposites()) {
      //遍历嵌套查询的属性映射关系对象列表
      //获取setter方法的参数类型
      final Class<?> propType = metaObject.getSetterType(innerResultMapping.getProperty());
      //获取类型处理器
      final TypeHandler<?> typeHandler = typeHandlerRegistry.getTypeHandler(propType);
      //获取属性值
      final Object propValue = typeHandler.getResult(rs, prependPrefix(innerResultMapping.getColumn(), columnPrefix));
      // issue #353 & #560 do not execute nested query if key is null
      if (propValue != null) {
        //属性值不为null,给参数对象设置属性值
        metaObject.setValue(innerResultMapping.getProperty(), propValue);
        foundValues = true;
      }
    }
    //如果当前查询结果不为空且参数对象的属性值不为null,返回参数对象
    return foundValues ? parameterObject : null;
  }

  /**实例化参数对象
   * @param parameterType         参数类型
   * @return                      参数对象
   */
  private Object instantiateParameterObject(Class<?> parameterType) {
    if (parameterType == null) {
      //未指定类型,默认HashMap
      return new HashMap<>();
    } else if (ParamMap.class.equals(parameterType)) {
      //如果指定的是ParamMap,返回HashMap
      return new HashMap<>(); // issue #649
    } else {
      //使用对象工厂创建对象
      return objectFactory.create(parameterType);
    }
  }

  //
  // DISCRIMINATOR
  //

  /**解析鉴别器的ResultMap
   * @param rs              结果集
   * @param resultMap       对象关系映射
   * @param columnPrefix    列名前缀
   * @return                鉴别器的对象关系映射
   * @throws SQLException   异常
   */
  public ResultMap resolveDiscriminatedResultMap(ResultSet rs, ResultMap resultMap, String columnPrefix) throws SQLException {
    Set<String> pastDiscriminators = new HashSet<>();
    //获取鉴别器
    Discriminator discriminator = resultMap.getDiscriminator();
    while (discriminator != null) {
      //获取鉴别器的中值
      final Object value = getDiscriminatorValue(rs, discriminator, columnPrefix);
      //很久属性值获取鉴别器的resultMapId
      final String discriminatedMapId = discriminator.getMapIdFor(String.valueOf(value));
      if (configuration.hasResultMap(discriminatedMapId)) {
        //如果有鉴别器resultMapId对应的resultMap
        resultMap = configuration.getResultMap(discriminatedMapId);
        Discriminator lastDiscriminator = discriminator;
        discriminator = resultMap.getDiscriminator();
        if (discriminator == lastDiscriminator || !pastDiscriminators.add(discriminatedMapId)) {
          //如果当前的鉴别器和上个鉴别器一样
          //或者已经处理过当前鉴别器了
          //break
          break;
        }
      } else {
        break;
      }
    }
    return resultMap;
  }

  /**获取鉴别器的值
   * @param rs
   * @param discriminator
   * @param columnPrefix
   * @return
   * @throws SQLException
   */
  private Object getDiscriminatorValue(ResultSet rs, Discriminator discriminator, String columnPrefix) throws SQLException {
    //获取鉴别器的结果映射对象
    final ResultMapping resultMapping = discriminator.getResultMapping();
    //获取类型处理器
    final TypeHandler<?> typeHandler = resultMapping.getTypeHandler();
    //获取结果
    return typeHandler.getResult(rs, prependPrefix(resultMapping.getColumn(), columnPrefix));
  }

  /**拼接前缀
   * @param columnName          列名
   * @param prefix              前缀
   * @return                    前缀拼上列名
   */
  private String prependPrefix(String columnName, String prefix) {
    if (columnName == null || columnName.length() == 0 || prefix == null || prefix.length() == 0) {
      return columnName;
    }
    return prefix + columnName;
  }

  //
  // HANDLE NESTED RESULT MAPS
  //

  /**处理嵌套层级的resultMap
   * @param rsw                 结果集包装器
   * @param resultMap           结果映射关系对象
   * @param resultHandler       结果处理器
   * @param rowBounds           分页参数
   * @param parentMapping       父级的结果映射关系对象
   * @throws SQLException       异常
   */
  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,未指定则返回当前的resultMap
      final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
      //创建行缓存key
      final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
      //根据缓存key获取部分对象
      Object partialObject = nestedResultObjects.get(rowKey);
      // issue #577 && #542
      if (mappedStatement.isResultOrdered()) {
        //如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。
        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;
    }
  }

  //
  // NESTED RESULT MAP (JOIN MAPPING)
  //

  /**处理嵌套层级的resultMapping
   * @param rsw               结果集包装器
   * @param resultMap         结果映射关系对象
   * @param metaObject        元数据
   * @param parentPrefix      父层级的列名前缀
   * @param parentRowKey      父层级的行缓存key
   * @param newObject         是否是新对象
   * @return                  是否有值
   */
  private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject) {
    boolean foundValues = false;
    for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
      //遍历所有的属性映射关系
      final String nestedResultMapId = resultMapping.getNestedResultMapId();
      if (nestedResultMapId != null && resultMapping.getResultSet() == null) {
        //如果当前属性指定了嵌套查询的resultMapId并且resultSet属性为空
        try {
          //获取列名前缀
          final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping);
          //获取嵌套层级的resultMap
          final ResultMap nestedResultMap = getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix);
          if (resultMapping.getColumnPrefix() == null) {
            // try to fill circular reference only when columnPrefix
            // is not specified for the nested result map (issue #215)
            Object ancestorObject = ancestorObjects.get(nestedResultMapId);
            if (ancestorObject != null) {
              if (newObject) {
                //将值设置到resultMap的collection或者association中
                linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
              }
              continue;
            }
          }
          //创建当前行缓存key
          final CacheKey rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
          //创建父节点和子节点组合的缓存key
          final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
          //从缓存中获取对象
          Object rowValue = nestedResultObjects.get(combinedKey);
          boolean knownValue = rowValue != null;
          //处理集合属性
          instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory
          if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw)) {
            //如果有非空列有值
            //获取值
            rowValue = getRowValue(rsw, nestedResultMap, combinedKey, columnPrefix, rowValue);
            if (rowValue != null && !knownValue) {
              //将值设置到resultMap的collection或者association中
              linkObjects(metaObject, resultMapping, rowValue);
              foundValues = true;
            }
          }
        } catch (SQLException e) {
          throw new ExecutorException("Error getting nested result map values for '" + resultMapping.getProperty() + "'.  Cause: " + e, e);
        }
      }
    }
    return foundValues;
  }

  /**获取列的前缀
   * @param parentPrefix        父层级的前缀
   * @param resultMapping       当前属性的映射关系
   * @return                    前缀
   */
  private String getColumnPrefix(String parentPrefix, ResultMapping resultMapping) {
    final StringBuilder columnPrefixBuilder = new StringBuilder();
    if (parentPrefix != null) {
      //拼接父级的列前缀
      columnPrefixBuilder.append(parentPrefix);
    }
    if (resultMapping.getColumnPrefix() != null) {
      //拼接自己的前缀
      columnPrefixBuilder.append(resultMapping.getColumnPrefix());
    }
    //返回前缀
    return columnPrefixBuilder.length() == 0 ? null : columnPrefixBuilder.toString().toUpperCase(Locale.ENGLISH);
  }

  /**判断是否非空的列有值
   * @param resultMapping         属性映射关系对象
   * @param columnPrefix          列名前缀
   * @param rsw                   结果集包装对象
   * @return                      是否有值
   * @throws SQLException         异常
   */
  private boolean anyNotNullColumnHasValue(ResultMapping resultMapping, String columnPrefix, ResultSetWrapper rsw) throws SQLException {
    //获取当前属性指定的列名
    Set<String> notNullColumns = resultMapping.getNotNullColumns();
    if (notNullColumns != null && !notNullColumns.isEmpty()) {
      //获取结果集
      ResultSet rs = rsw.getResultSet();
      for (String column : notNullColumns) {
        //读取列的值
        rs.getObject(prependPrefix(column, columnPrefix));
        if (!rs.wasNull()) {
          //不为空返回true
          return true;
        }
      }
      return false;
    } else if (columnPrefix != null) {
      for (String columnName : rsw.getColumnNames()) {
        if (columnName.toUpperCase().startsWith(columnPrefix.toUpperCase())) {
          //如果结果集列中中包含当前列,返回true
          return true;
        }
      }
      return false;
    }
    return true;
  }

  /**获取嵌套层级的resultMap
   * @param rs
   * @param nestedResultMapId
   * @param columnPrefix
   * @return
   * @throws SQLException
   */
  private ResultMap getNestedResultMap(ResultSet rs, String nestedResultMapId, String columnPrefix) throws SQLException {
    //根据嵌套的resultMapId获取resultMap
    ResultMap nestedResultMap = configuration.getResultMap(nestedResultMapId);
    //解析鉴别器
    return resolveDiscriminatedResultMap(rs, nestedResultMap, columnPrefix);
  }

  //
  // UNIQUE RESULT KEY
  //

  /**计算缓存key
   * @param resultMap           结果映射关系对象
   * @param rsw                 结果集包装器
   * @param columnPrefix        列前缀
   * @return                    缓存key
   * @throws SQLException       异常
   */
  private CacheKey createRowKey(ResultMap resultMap, ResultSetWrapper rsw, String columnPrefix) throws SQLException {
    //创建一个缓存key对象
    final CacheKey cacheKey = new CacheKey();
    //使用resultMapId计算一次缓存key
    cacheKey.update(resultMap.getId());
    ///获取用于计算缓存key的resultMapping集合
    List<ResultMapping> resultMappings = getResultMappingsForRowKey(resultMap);
    if (resultMappings.isEmpty()) {
      //如果是空集合
      if (Map.class.isAssignableFrom(resultMap.getType())) {
        //指定ResultMap的类型指定的是Map时
        //使用map的方式计算缓存key
        createRowKeyForMap(rsw, cacheKey);
      } else {
        //对未匹配的属性计算缓存key
        createRowKeyForUnmappedProperties(resultMap, rsw, cacheKey, columnPrefix);
      }
    } else {
      //使用匹配属性的方式计算缓存key
      createRowKeyForMappedProperties(resultMap, rsw, cacheKey, resultMappings, columnPrefix);
    }
    if (cacheKey.getUpdateCount() < 2) {
      //如果最终缓存key的计算次数小于2,返回一个空缓存key
      return CacheKey.NULL_CACHE_KEY;
    }
    return cacheKey;
  }

  /**组合缓存key值
   * @param rowKey            当前行的缓存key
   * @param parentRowKey      父级缓存key
   * @return                  新的缓存key
   */
  private CacheKey combineKeys(CacheKey rowKey, CacheKey parentRowKey) {
    if (rowKey.getUpdateCount() > 1 && parentRowKey.getUpdateCount() > 1) {
      CacheKey combinedKey;
      try {
        //clone新对象,不影响之前的缓存key
        combinedKey = rowKey.clone();
      } catch (CloneNotSupportedException e) {
        throw new ExecutorException("Error cloning cache key.  Cause: " + e, e);
      }
      //用父级key重新计算新的缓存key
      combinedKey.update(parentRowKey);
      return combinedKey;
    }
    //如果当前行的key或父级key是未计算过缓存hash值的cacheKey,返回空缓存key
    return CacheKey.NULL_CACHE_KEY;
  }

  /**获取用于生成行数据缓存的属性映射关系对象结合
   * @param resultMap
   * @return
   */
  private List<ResultMapping> getResultMappingsForRowKey(ResultMap resultMap) {
    //id可以唯一确定行值,优先取id
    //先获取id类型的映射关系集合
    List<ResultMapping> resultMappings = resultMap.getIdResultMappings();
    if (resultMappings.isEmpty()) {
      //如果未指定id字段,再获取属性映射关系集合
      resultMappings = resultMap.getPropertyResultMappings();
    }
    return resultMappings;
  }

  /**为匹配的自动创建缓存key
   * @param resultMap           结果映射关系对象
   * @param rsw                 结果集包装器
   * @param cacheKey            缓存key
   * @param resultMappings      属性的映射关系对象集合
   * @param columnPrefix        列前缀
   * @throws SQLException       异常
   */
  private void createRowKeyForMappedProperties(ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, List<ResultMapping> resultMappings, String columnPrefix) throws SQLException {
    for (ResultMapping resultMapping : resultMappings) {
      //遍历属性映射对象集合
      if (resultMapping.isSimple()) {
        //只处理简单类型的映射关系
        //属性拼接列前缀
        final String column = prependPrefix(resultMapping.getColumn(), columnPrefix);
        //获取类型处理器
        final TypeHandler<?> th = resultMapping.getTypeHandler();
        //获取已匹配的列名
        List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
        // Issue #114
        if (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH))) {
          //如果包含当前列名
          //获取列的值
          final Object value = th.getResult(rsw.getResultSet(), column);
          if (value != null || configuration.isReturnInstanceForEmptyRow()) {
            //用有值得列和值计算缓存key
            cacheKey.update(column);
            cacheKey.update(value);
          }
        }
      }
    }
  }

  /**用未匹配的属性创建缓存key
   * @param resultMap           结果映射关系对象
   * @param rsw                 结果集包装器
   * @param cacheKey            缓存key
   * @param columnPrefix        列前缀
   * @throws SQLException       异常
   */
  private void createRowKeyForUnmappedProperties(ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, String columnPrefix) throws SQLException {
    //创建一个resultMap的java类的元Class对象
    final MetaClass metaType = MetaClass.forClass(resultMap.getType(), reflectorFactory);
    //获取未匹配的列
    List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
    for (String column : unmappedColumnNames) {
      String property = column;
      if (columnPrefix != null && !columnPrefix.isEmpty()) {
        //如果指定了列前缀
        // When columnPrefix is specified, ignore columns without the prefix.
        if (column.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
          //去除前缀
          property = column.substring(columnPrefix.length());
        } else {
          continue;
        }
      }
      if (metaType.findProperty(property, configuration.isMapUnderscoreToCamelCase()) != null) {
        //如果找到该属性值
        String value = rsw.getResultSet().getString(column);
        if (value != null) {
          //用有值得列和值计算缓存key
          cacheKey.update(column);
          cacheKey.update(value);
        }
      }
    }
  }

  /**对Map类型的行数据创建缓存key
   * @param rsw                   结果集包装对象
   * @param cacheKey              缓存key
   * @throws SQLException         异常
   */
  private void createRowKeyForMap(ResultSetWrapper rsw, CacheKey cacheKey) throws SQLException {
    List<String> columnNames = rsw.getColumnNames();
    for (String columnName : columnNames) {
      //遍历所有列
      final String value = rsw.getResultSet().getString(columnName);
      if (value != null) {
        //用列值非空的列和值进行缓存key的计算
        cacheKey.update(columnName);
        cacheKey.update(value);
      }
    }
  }

  /**将值设置到resultMap的collection或者association中
   * @param metaObject          元数据对象
   * @param resultMapping       当前属性的映射关系
   * @param rowValue            当前值
   */
  private void linkObjects(MetaObject metaObject, ResultMapping resultMapping, Object rowValue) {
    //判断当前属性是否是集合类型,如果是,返回集合
    final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);
    if (collectionProperty != null) {
      //返回的集合对象不为nul
      //为集合对象创建一个元数据
      final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty);
      //讲值设置add到集合中
      targetMetaObject.add(rowValue);
    } else {
      //不是集合类型,直接设置值
      metaObject.setValue(resultMapping.getProperty(), rowValue);
    }
  }

  /**实例化一个集合属性
   * @param resultMapping           列和属性值得匹配关系
   * @param metaObject              元数据对象
   * @return                        结果对象
   */
  private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) {
    //获取属性名
    final String propertyName = resultMapping.getProperty();
    //获取属性值
    Object propertyValue = metaObject.getValue(propertyName);
    if (propertyValue == null) {
      //获取javaType
      Class<?> type = resultMapping.getJavaType();
      if (type == null) {
        //类型为空时从元数据中获取Setter方法的类型
        type = metaObject.getSetterType(propertyName);
      }
      try {
        if (objectFactory.isCollection(type)) {
          //如果类型为集合类型,创建一个集合
          propertyValue = objectFactory.create(type);
          //给属性设置值
          metaObject.setValue(propertyName, propertyValue);
          //返回集合
          return propertyValue;
        }
      } catch (Exception e) {
        throw new ExecutorException("Error instantiating collection property for result '" + resultMapping.getProperty() + "'.  Cause: " + e, e);
      }
    } else if (objectFactory.isCollection(propertyValue.getClass())) {
      //如果是集合类型,直接返回属性值
      return propertyValue;
    }
    return null;
  }

  /**判断返回的结果对象是否有类型处理器
   * @param rsw                   结果集包装对象
   * @param resultType            返回对象的类对象
   * @return                      是否有类型处理器
   */
  private boolean hasTypeHandlerForResultObject(ResultSetWrapper rsw, Class<?> resultType) {
    if (rsw.getColumnNames().size() == 1) {
      return typeHandlerRegistry.hasTypeHandler(resultType, rsw.getJdbcType(rsw.getColumnNames().get(0)));
    }
    return typeHandlerRegistry.hasTypeHandler(resultType);
  }

}

总结

本章主要是介绍了结果集的封装实现.这些所有的操作都是依赖DefaultResultSetHandler完成的.
主要是对三类方法进行操作的.

  1. 处理普通查询的结果集
  2. 处理游标结果集
  3. 处理存储中的输出参数

喜欢的小伙伴请动动小手关注和点赞吧,也可留言一起探讨怎样更好的学习源码!!!

mybatis带中文注释源码地址

github地址

文章链接

Mybatis源码学习(一)初探执行流程
Mybatis源码学习(二)配置文件解析到SqlSessionFactory构建
Mybatis源码学习(三)SqlSession详解
Mybatis源码学习(四)自定义Mapper方法执行流程
Mybatis源码学习(五)Executor和StatementHandler详解
Mybatis源码学习(六)结果集自动封装机制
Mybatis源码学习(七)mybatis缓存详解
Mybatis源码学习(八)Mybatis设计模式总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值