`
18211103738
  • 浏览: 81158 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

MyBatis查询的源码分析

阅读更多

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

String resource = "mybatis.cfg.xml";  
Reader reader = Resources.getResourceAsReader(resource);  
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);  
	
SqlSession sqlSession = ssf.openSession();  
	
try {  
	List<User> 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:
public class DefaultSqlSession implements SqlSession {

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

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

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

  @Override
  public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
	//MappedStatement是mybatis根据<select id="selectByExample" resultMap="ResultMap" ... />创建的映射对象
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

... ...
}
/**
  * 行数限制
  */
public class RowBounds {

  public static final int NO_ROW_OFFSET = 0;
  public static final int NO_ROW_LIMIT = Integer.MAX_VALUE;
  public static final RowBounds DEFAULT = new RowBounds();

  private int offset;
  private int limit;

  public RowBounds() {
    this.offset = NO_ROW_OFFSET;
    this.limit = NO_ROW_LIMIT;
  }

  public RowBounds(int offset, int limit) {
    this.offset = offset;
    this.limit = limit;
  }
... ...
}

  

  • 当我们启用缓存后查询执行器Executor为CachingExector:
public class CachingExecutor implements Executor {

  private Executor delegate;
  private TransactionalCacheManager tcm = new TransactionalCacheManager();

  public CachingExecutor(Executor delegate) {
    this.delegate = delegate;//这里的delegate为abstract class BaseExecutor implements Executor
    delegate.setExecutorWrapper(this);
  }
... ...

  @Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

  @Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
      throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
      flushCacheIfRequired(ms);//如果<select id="selectByExample" resultMap="ResultMap" flushCache="true" ... />中设置flushCache="true",则清除缓存
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, parameterObject, boundSql);//确保查询不包括输出参数,因为缓存程序不支持输出参数
        @SuppressWarnings("unchecked")
        List<E> list = (List<E>) tcm.getObject(cache, key);//从缓存管理器中获取缓存(缓存管理器是对各区块缓存的统一管理工具)
        if (list == null) {	//如果从缓存中获取不到,则执行查询
          list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
          tcm.putObject(cache, key, list); //将查询到的结果放入缓存
        }
        return list;
      }
    }
    return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

... ...

}

 

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

... ...

  @Override
  public <E> List<E> 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.<E>query(stmt, resultHandler); //执行查询
  }

... ...

}

 

  • StatementHandler一般为路由StatementHandler,即RoutingStatementHandler:
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 <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();	//执行查询
    return resultSetHandler.<E> handleResultSets(ps);	//处理结果集
  }
... ...
}

 

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

... ...

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

    final List<Object> multipleResults = new ArrayList<Object>();

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

    List<ResultMap> 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<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());
    }
  }

... ...

  /**
* 处理所有行记录中的值
*/
  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<Object> resultContext = new DefaultResultContext<Object>();
    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<Object> resultContext = new DefaultResultContext<Object>();
    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<CacheKey, Object>)中获取原对象
      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<ResultMapping> 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<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);
        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<ResultMapping> resultMappings;	//所有内嵌的结果映射
  private List<ResultMapping> idResultMappings;	//所有内嵌的ID结果映射
  private List<ResultMapping> constructorResultMappings;	//所有构造映射
  private List<ResultMapping> propertyResultMappings;		//所有的属性映射
... ...

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

 

  • 备注:DefaultResultSetHandler中CacheKey的创建策略
<resultMap id="BaseResultMap" type="com.muwu.mjh.product.model.Cupboard" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="mark" property="mark" jdbcType="VARCHAR" />
<association property="unit" javaType="com.muwu.mjh.system.model.Unit" autoMapping="false">
    	<id property="id" column="unit_id"/>
    	<result property="name" column="unit_name"/>
    </association>
	<association property="productType" javaType="com.muwu.mjh.product.model.ProductType" autoMapping="false">
    	<id property="id" column="product_type_id"/>
    	<result property="name" column="product_type_name"/>
    	<result property="parentId" column="parent_id"/>
    </association>
    <collection property="modules" ofType="com.muwu.mjh.product.model.cupboard.Module" autoMapping="false" >
    	<id property="id" column="module_id"/>
    	<id property="sort" column="module_sort"/>
    	<result property="name" column="module_name"/>
    	<result property="mark" column="module_mark"/>
    	<collection property="components" ofType="com.muwu.mjh.product.model.cupboard.Component" autoMapping="false">
    		<id property="id" column="component_id"/>
    		<result property="name" column="component_name"/>
    		<result property="mark" column="component_mark"/>
    		<result property="image" column="component_image"/>
    		<result property="picture" column="component_picture"/>
    	</collection>
    </collection>
</resultMap>

 

映射时生成的缓存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

 

可见被<id property="..." column="..."/>标注的属性和字段值都会作为CacheKey的一部分

  • 大小: 22.2 KB
  • 大小: 20.6 KB
  • 大小: 15.8 KB
  • 大小: 13.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics