MyBatis查询的源码分析

阅读更多

如下为mybatis的一个集合查询: 

String resource = "mybatis.cfg.xml";  
Reader reader = Resources.getResourceAsReader(resource);  
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);  
	
SqlSession sqlSession = ssf.openSession();  
	
try {  
	List users = sqlSession.selectList("User.selectUser", "1");  //查询状态为1的用户
	for (User user : users) {
		System.out.println(user);  
	}
} catch (Exception e) {  
	e.printStackTrace();  
} finally {  
	sqlSession.close();
}

  

  • 其中SqlSession默认为DefaultSqlSession:MyBatis查询的源码分析_第1张图片
public class DefaultSqlSession implements SqlSession {

  private Configuration configuration;
  private Executor executor;
... ...

  @Override
  public  List selectList(String statement) {
    return this.selectList(statement, null);
  }

  @Override
  public  List selectList(String statement, Object parameter) {
    return this.selectList(statement, parameter, RowBounds.DEFAULT);	//其中RowBounds.DEFAULT为new RowBounds();
  }

  @Override
  public  List selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
	//MappedStatement是mybatis根据中设置flushCache="true",则清除缓存
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, parameterObject, boundSql);//确保查询不包括输出参数,因为缓存程序不支持输出参数
        @SuppressWarnings("unchecked")
        List list = (List) tcm.getObject(cache, key);//从缓存管理器中获取缓存(缓存管理器是对各区块缓存的统一管理工具)
        if (list == null) {	//如果从缓存中获取不到,则执行查询
          list = delegate. query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
          tcm.putObject(cache, key, list); //将查询到的结果放入缓存
        }
        return list;
      }
    }
    return delegate. query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

... ...

}

 

  • CachingExecutor中的执行器代理delegate一般为ReuseExecutor:
public class ReuseExecutor extends BaseExecutor {

... ...

  @Override
  public  List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
    Configuration configuration = ms.getConfiguration();
    StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
    Statement stmt = prepareStatement(handler, ms.getStatementLog());
    return handler.query(stmt, resultHandler); //执行查询
  }

... ...

}

 

  • StatementHandler一般为路由StatementHandler,即RoutingStatementHandler:MyBatis查询的源码分析_第3张图片
public class RoutingStatementHandler implements StatementHandler {

  private final StatementHandler delegate;

  public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
/*这里的switch-case即是传说中的策略模式*/
    switch (ms.getStatementType()) {
      case STATEMENT:
        delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
        break;
      case PREPARED:
        delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
        break;
      case CALLABLE:
        delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
        break;
      default:
        throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
    }

  }

 

  • RoutingStatementHandler其中的StatementHandler代理delegate,通常为PreparedStatementHandler;其中的query(...)方法通过调用ResultHandler的handleResultSets(...)封装查询结果:
public class PreparedStatementHandler extends BaseStatementHandler {

... ...
  @Override
  public  List query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();	//执行查询
    return resultSetHandler. handleResultSets(ps);	//处理结果集
  }
... ...
}

 

  • ResultSetHandler只有一个默认结果集处理器DefaultResultSetHandler:
public interface ResultSetHandler {
  /**
    * 处理结果集
    */
   List handleResultSets(Statement stmt) throws SQLException;

... ...

}
public class DefaultResultSetHandler implements ResultSetHandler {
  ... ...
  // nested resultmaps
  private final Map nestedResultObjects = new HashMap();//嵌套结果缓存
  private final Map ancestorObjects = new HashMap();//祖对象缓存,即最外层的对象缓存
  private final Map ancestorColumnPrefix = new HashMap();
  ... ...
  
  /**
    * 处理所有的结果集(一次查询可能有多个语句,所以可能有多个结果集)
    */
  @Override
  public List handleResultSets(Statement stmt) throws SQLException {
    ErrorContext.instance().activity("handling results").object(mappedStatement.getId());

    final List multipleResults = new ArrayList();

    int resultSetCount = 0;
    ResultSetWrapper rsw = getFirstResultSet(stmt);//获取java.sql.ResultSet的第一个结果集(此时sql已被执行)

    List resultMaps = mappedStatement.getResultMaps();
    int resultMapCount = resultMaps.size();
    validateResultMapsCount(rsw, resultMapCount);
    while (rsw != null && resultMapCount > resultSetCount) {	//遍历所有的结果集(一般仅一个结果集,因为通常仅一条查询语句)
      ResultMap resultMap = resultMaps.get(resultSetCount);
      handleResultSet(rsw, resultMap, multipleResults, null);	//根据ResultSetWrapper和ResultMap处理结果集
      rsw = getNextResultSet(stmt);
      cleanUpAfterHandlingResultSet();
      resultSetCount++;
    }

/*---------该方法中的以下代码暂且不做分析------------*/
    String[] resultSets = mappedStatement.getResulSets();
    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);
  }

... ...

  private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List 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());
    }
  }

... ...

  /**
* 处理所有行记录中的值
*/
  private void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
    if (resultMap.hasNestedResultMaps()) {
      ensureNoRowBounds();
      checkResultHandler();
      handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);//嵌套映射
    } else {
      handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);//简单映射
    }
  }

... ...

  /**
    * 处理行值集到简单结果的映射
    */
  private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
      throws SQLException {
    DefaultResultContext resultContext = new DefaultResultContext();
    skipRows(rsw.getResultSet(), rowBounds);
    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
      Object rowValue = getRowValue(rsw, discriminatedResultMap);
      storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
    }
  }

... ...

   /**
    * 处理行值集到嵌套结果的映射
    */
   private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
    final DefaultResultContext resultContext = new DefaultResultContext();
    skipRows(rsw.getResultSet(), rowBounds);
    Object rowValue = null;
    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
      final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
      final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
      Object partialObject = nestedResultObjects.get(rowKey);//尝试从nestedResultObjects(是HashMap)中获取原对象
      if (mappedStatement.isResultOrdered()) {
        if (partialObject == null && rowValue != null) {
          nestedResultObjects.clear();
          storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
        }
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject);//获取行值
      } else {
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject);//获取行值
        if (partialObject == null) {
          storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
        }
      }
    }
    if (rowValue != null && mappedStatement.isResultOrdered() && shouldProcessMoreRows(resultContext, rowBounds)) {
      storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
    }
  }

... ...


  /**
    * 创建缓存的KEY(具体key的生成策略可详见文末)
    */
  private CacheKey createRowKey(ResultMap resultMap, ResultSetWrapper rsw, String columnPrefix) throws SQLException {
    final CacheKey cacheKey = new CacheKey();
    cacheKey.update(resultMap.getId());
    List resultMappings = getResultMappingsForRowKey(resultMap);
    if (resultMappings.size() == 0) {
      if (Map.class.isAssignableFrom(resultMap.getType())) {
        createRowKeyForMap(rsw, cacheKey);
      } else {
        createRowKeyForUnmappedProperties(resultMap, rsw, cacheKey, columnPrefix);
      }
    } else {
      createRowKeyForMappedProperties(resultMap, rsw, cacheKey, resultMappings, columnPrefix);
    }
    return cacheKey;
  }

... ...

  /**
    * 从查询的一条行记录中获取需要映射为结果属性的值
    */
  private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, CacheKey absoluteKey, String columnPrefix, Object partialObject) throws SQLException {
    final String resultMapId = resultMap.getId();
    Object resultObject = partialObject;
/*如果传过来的原对象不为空,则向其中设置属性值;
否则,创建一个新结果对象作为原对象,然后设置属性值*/
    if (resultObject != null) {
      final MetaObject metaObject = configuration.newMetaObject(resultObject);
      putAncestor(absoluteKey, resultObject, resultMapId, columnPrefix);
      applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);	//应用嵌套映射
      ancestorObjects.remove(absoluteKey);
    } else {
      final ResultLoaderMap lazyLoader = new ResultLoaderMap();
      resultObject = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
      if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
        final MetaObject metaObject = configuration.newMetaObject(resultObject);
        boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();
        if (shouldApplyAutomaticMappings(resultMap, true)) {
          foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
        }
	   //属性映射
        foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
        putAncestor(absoluteKey, resultObject, resultMapId, columnPrefix);
	   //嵌套映射
        foundValues = applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;
        ancestorObjects.remove(absoluteKey);
        foundValues = lazyLoader.size() > 0 || foundValues;
        resultObject = foundValues ? resultObject : null;
      }
      if (combinedKey != CacheKey.NULL_CACHE_KEY) {
        nestedResultObjects.put(combinedKey, resultObject);
      }
    }
    return resultObject;
  }

... ...

  /**
    * 应用属性映射
    */
  private boolean applyPropertyMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, ResultLoaderMap lazyLoader, String columnPrefix)
      throws SQLException {
    final List mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
    boolean foundValues = false;
    final List 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);
        final String property = propertyMapping.getProperty();
        if (value != DEFERED
            && property != null
            && (value != null || (configuration.isCallSettersOnNulls() && !metaObject.getSetterType(property).isPrimitive()))) {
          metaObject.setValue(property, value);
        }
        if (value != null || value == DEFERED) {
          foundValues = true;
        }
      }
    }
    return foundValues;
  }

... ...

   /**
    * 应用嵌套结果映射
    */
   private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject) {
    boolean foundValues = false;
//循环结果映射中所有的属性映射,如果属性为对象,即嵌套结果映射,则递归调用getRowValue(...)方法
    for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
      final String nestedResultMapId = resultMapping.getNestedResultMapId();
      if (nestedResultMapId != null && resultMapping.getResultSet() == null) {
        try {
          final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping);
          final ResultMap nestedResultMap = getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix);
          CacheKey rowKey = null;
          Object ancestorObject = null;
          if (ancestorColumnPrefix.containsKey(nestedResultMapId)) {
            rowKey = createRowKey(nestedResultMap, rsw, ancestorColumnPrefix.get(nestedResultMapId));
            ancestorObject = ancestorObjects.get(rowKey);
          }
          if (ancestorObject != null) {
            if (newObject) {
              linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
            }
          } else {
            rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
            final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
            Object rowValue = nestedResultObjects.get(combinedKey);
            boolean knownValue = (rowValue != null);
            instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory            
            if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw.getResultSet())) {
		   //递归调用getRowValue(...)方法
              rowValue = getRowValue(rsw, nestedResultMap, combinedKey, rowKey, columnPrefix, rowValue);
              if (rowValue != null && !knownValue) {
                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;
  }
} 
  
/**
  * 结果映射
  */
public class ResultMap {
  private String id;		//结果映射ID
  private Class type;	//映射结果类型
  private List resultMappings;	//所有内嵌的结果映射
  private List idResultMappings;	//所有内嵌的ID结果映射
  private List constructorResultMappings;	//所有构造映射
  private List propertyResultMappings;		//所有的属性映射
... ...

  private ResultMap() {
  }
... ...
}

 

  • 备注:DefaultResultSetHandler中CacheKey的创建策略

    
    
    

    	
    	
    
	
    	
    	
    	
    
    
    	
    	
    	
    	
    	
    		
    		
    		
    		
    		
    	
    

 

映射时生成的缓存key依次形如:

 

13544163:-1571759273:com.muwu.mjh.product.mapper.CupboardMapper.

    RichResultMap:id:16942

 

-2046111186:1023173599:com.muwu.mjh.product.mapper.CupboardMapper.

    mapper_resultMap[RichResultMap]_association[unit]:unit_id:10

 

2024729156:2397089841:com.muwu.mjh.product.mapper.CupboardMapper.

    mapper_resultMap[RichResultMap]_association[productType]:product_type_id:19

 

1199939766:-5622484385:com.muwu.mjh.product.mapper.CupboardMapper.

    mapper_resultMap[RichResultMap]_collection[modules]:module_id:51:module_sort:0

 

559266669:-1005085733:com.muwu.mjh.product.mapper.CupboardMapper.

    mapper_resultMap[RichResultMap]_collection[modules]_collection[components]:component_id:200

 

可见被标注的属性和字段值都会作为CacheKey的一部分

  • MyBatis查询的源码分析_第4张图片
  • 大小: 22.2 KB
  • MyBatis查询的源码分析_第5张图片
  • 大小: 20.6 KB
  • MyBatis查询的源码分析_第6张图片
  • 大小: 15.8 KB
  • MyBatis查询的源码分析_第7张图片
  • 大小: 13.1 KB
  • 查看图片附件

你可能感兴趣的:(MyBatis查询的源码分析)