Mybatis工作机制源码分析—一次select请求处理流程

来源:互联网 发布:淘宝网天猫女装羽绒服 编辑:程序博客网 时间:2024/05/17 13:08

        本文从源码分析的角度分析Mybatis一次select请求处理流程。

select整体处理流程

时序图


DefaultSqlSession.selectOne工作流程

时序图


DynamicSqlSource构建BoundSql工作流程


相关源码

/** DefaultSqlSession.java */public <T> T selectOne(String statement, Object parameter) {// Popular vote was to return null on 0 results and throw exception on too many.List<T> list = this.<T>selectList(statement, parameter);if (list.size() == 1) {return list.get(0);} else if (list.size() > 1) {throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());} else {return null;}}public <E> List<E> selectList(String statement, Object parameter) {return this.selectList(statement, parameter, RowBounds.DEFAULT);}public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {try {// 根据statement id获取MappedStatementMappedStatement 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();}}/** CachingExecutor.java */public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {// MappedStatement构建BoundSql,实际用DynamicSqlSource或StaticSqlSource构建BoundSqlBoundSql boundSql = ms.getBoundSql(parameterObject);// 构建CacheKeyCacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}/** MappedStatement.java */public BoundSql getBoundSql(Object parameterObject) {BoundSql boundSql = sqlSource.getBoundSql(parameterObject);List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();if (parameterMappings == null || parameterMappings.isEmpty()) {boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);}// check for nested result maps in parameter mappings (issue #30)for (ParameterMapping pm : boundSql.getParameterMappings()) {String rmId = pm.getResultMapId();if (rmId != null) {ResultMap rm = configuration.getResultMap(rmId);if (rm != null) {hasNestedResultMaps |= rm.hasNestedResultMaps();}  }}return boundSql;}/** DynamicSqlSource.java */// DynamicSqlSource构建BoundSqlpublic BoundSql getBoundSql(Object parameterObject) {DynamicContext context = new DynamicContext(configuration, parameterObject);// 根据sql语句中的<where>、<foreach>等元素,动态组建完整的sql语句rootSqlNode.apply(context);SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();// context.getSql()获取的sql语句是完整sql语句的原始形式,包括#{}等// 将sql语句解析为StaticSqlSourceSqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());// 用StaticSqlSource构建BoundSqlBoundSql boundSql = sqlSource.getBoundSql(parameterObject);// 添加metaParameterfor (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());}return boundSql;}/** MixedSqlNode.java */public boolean apply(DynamicContext context) {for (SqlNode sqlNode : contents) {sqlNode.apply(context);}return true;}/** StaticTextSqlNode.java */public boolean apply(DynamicContext context) {context.appendSql(text);return true;}/** TrimSqlNode.java */public boolean apply(DynamicContext context) {FilteredDynamicContext filteredDynamicContext = new FilteredDynamicContext(context);boolean result = contents.apply(filteredDynamicContext);filteredDynamicContext.applyAll();return result;}/** TrimSqlNode.FilteredDynamicContext.java */public void appendSql(String sql) {sqlBuffer.append(sql);}public void applyAll() {sqlBuffer = new StringBuilder(sqlBuffer.toString().trim());String trimmedUppercaseSql = sqlBuffer.toString().toUpperCase(Locale.ENGLISH);if (trimmedUppercaseSql.length() > 0) {applyPrefix(sqlBuffer, trimmedUppercaseSql);applySuffix(sqlBuffer, trimmedUppercaseSql);}delegate.appendSql(sqlBuffer.toString());}/** SqlSourceBuilder.java */public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);// 解析#{}形式的参数GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);// 解析后的sql为用"?"替换#{}参数,且提取对应参数的ParameterMappingString sql = parser.parse(originalSql);// 以StaticSqlSource为解析结果return new StaticSqlSource(configuration, sql, handler.getParameterMappings());}/** BoundSql.java */public void setAdditionalParameter(String name, Object value) {metaParameters.setValue(name, value);}/** CachingExecutor.java */public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {return delegate.createCacheKey(ms, parameterObject, rowBounds, boundSql);}/** BaseExecutor.java */// 创建CacheKey,用MappedStatement、parameterObject、rowBounds、boundSql影响CacheKey的hashCodepublic CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {if (closed) {throw new ExecutorException("Executor was closed.");}CacheKey cacheKey = new CacheKey();// cacheKey关联MappedStatement idcacheKey.update(ms.getId());// cacheKey关联rowBounds offsetcacheKey.update(Integer.valueOf(rowBounds.getOffset()));// cacheKey关联Offset limitcacheKey.update(Integer.valueOf(rowBounds.getLimit()));// cacheKey关联boundSql sqlcacheKey.update(boundSql.getSql());List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();// mimic DefaultParameterHandler logicfor (int i = 0; i < parameterMappings.size(); i++) {ParameterMapping parameterMapping = parameterMappings.get(i);if (parameterMapping.getMode() != ParameterMode.OUT) {Object value;String propertyName = parameterMapping.getProperty();if (boundSql.hasAdditionalParameter(propertyName)) {value = boundSql.getAdditionalParameter(propertyName);} else if (parameterObject == null) {value = null;} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {value = parameterObject;} else {MetaObject metaObject = configuration.newMetaObject(parameterObject);value = metaObject.getValue(propertyName);}// cacheKey关联parameterMapping valuecacheKey.update(value);}}if (configuration.getEnvironment() != null) {// cacheKey关联environment idcacheKey.update(configuration.getEnvironment().getId());}return cacheKey;}    /** CachingExecutor.java */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) {// CachingExecutor缓存处理,MappedStatement级缓存结合TransactionalCache缓存flushCacheIfRequired(ms);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); // issue #578 and #116}return list;}}return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}/** BaseExecutor.java */public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());if (closed) {throw new ExecutorException("Executor was closed.");}if (queryStack == 0 && ms.isFlushCacheRequired()) {clearLocalCache();}List<E> list;try {queryStack++;// 查看本地缓存,有则直接返回list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;if (list != null) {// 处理本地缓存的输出参数handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);} else {// 从Database查询list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {queryStack--;}if (queryStack == 0) {for (DeferredLoad deferredLoad : deferredLoads) {deferredLoad.load();}// issue #601deferredLoads.clear();if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {// MappedStatement级别的缓存,则清空本地缓存clearLocalCache();}}return list;}private void handleLocallyCachedOutputParameters(MappedStatement ms, CacheKey key, Object parameter, BoundSql boundSql) {if (ms.getStatementType() == StatementType.CALLABLE) {final Object cachedParameter = localOutputParameterCache.getObject(key);if (cachedParameter != null && parameter != null) {final MetaObject metaCachedParameter = configuration.newMetaObject(cachedParameter);final MetaObject metaParameter = configuration.newMetaObject(parameter);for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {if (parameterMapping.getMode() != ParameterMode.IN) {final String parameterName = parameterMapping.getProperty();final Object cachedValue = metaCachedParameter.getValue(parameterName);metaParameter.setValue(parameterName, cachedValue);}}}}}private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {List<E> list;localCache.putObject(key, EXECUTION_PLACEHOLDER);try {// 从Database查询list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);} finally {// 清空本地之前CacheKey对应的缓存localCache.removeObject(key);}// 将查询结果key——list缓存到localCachelocalCache.putObject(key, list);if (ms.getStatementType() == StatementType.CALLABLE) {// 将key——parameter缓存到localOutputParameterCachelocalOutputParameterCache.putObject(key, parameter);}return list;}/** SimpleExecutor.java */public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {Statement stmt = null;try {Configuration configuration = ms.getConfiguration();StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);stmt = prepareStatement(handler, ms.getStatementLog());return handler.<E>query(stmt, resultHandler);} finally {// close StatementcloseStatement(stmt);}}/** RoutingStatementHandler.java */public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {return delegate.<E>query(statement, resultHandler);}/** PreparedStatementHandler.java */public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {PreparedStatement ps = (PreparedStatement) statement;ps.execute();return resultSetHandler.<E> handleResultSets(ps);}

DefaultResultSetHandler.handleResultSets工作流程

时序图


相关源码

/** DefaultResultSetHandler.java */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);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);// 获取Next ResultSet继续处理rsw = getNextResultSet(stmt);cleanUpAfterHandlingResultSet();resultSetCount++;}// 处理内嵌的ResultMapString[] 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++;}}// 返回ResultSet解析结果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);// defaultResultHandler将resultList转交给multipleResultsmultipleResults.add(defaultResultHandler.getResultList());} else {handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);}}} finally {// close resultsetscloseResultSet(rsw.getResultSet());}}

DefaultResultSetHandler.handleRowValues工作流程

时序图


相关源码

/** DefaultResultSetHandler.java */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);// 获取row对应的记录结果对象Object rowValue = getRowValue(rsw, discriminatedResultMap);// 将结果保存到resultHandlerstoreObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());}}private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {rs.absolute(rowBounds.getOffset());}} else {根据rowBounds offset,skipRowsfor (int i = 0; i < rowBounds.getOffset(); i++) {rs.next();}}}private boolean shouldProcessMoreRows(ResultContext<?> context, RowBounds rowBounds) throws SQLException {return !context.isStopped() && context.getResultCount() < rowBounds.getLimit();}public ResultMap resolveDiscriminatedResultMap(ResultSet rs, ResultMap resultMap, String columnPrefix) throws SQLException {Set<String> pastDiscriminators = new HashSet<String>();Discriminator discriminator = resultMap.getDiscriminator();while (discriminator != null) {final Object value = getDiscriminatorValue(rs, discriminator, columnPrefix);final String discriminatedMapId = discriminator.getMapIdFor(String.valueOf(value));if (configuration.hasResultMap(discriminatedMapId)) {resultMap = configuration.getResultMap(discriminatedMapId);Discriminator lastDiscriminator = discriminator;discriminator = resultMap.getDiscriminator();if (discriminator == lastDiscriminator || !pastDiscriminators.add(discriminatedMapId)) {break;}} else {break;}}return resultMap;}private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {final ResultLoaderMap lazyLoader = new ResultLoaderMap();// 创建ResultObject对象,未赋database获取来的值Object resultObject = createResultObject(rsw, resultMap, lazyLoader, null);if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {final MetaObject metaObject = configuration.newMetaObject(resultObject);boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();if (shouldApplyAutomaticMappings(resultMap, false)) {foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;}foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;foundValues = lazyLoader.size() > 0 || foundValues;resultObject = foundValues ? resultObject : null;return resultObject;}return resultObject;}private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException {final List<Class<?>> constructorArgTypes = new ArrayList<Class<?>>();final List<Object> constructorArgs = new ArrayList<Object>();// 创建ResultObject对象final Object resultObject = createResultObject(rsw, resultMap, constructorArgTypes, constructorArgs, columnPrefix);if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();for (ResultMapping propertyMapping : propertyMappings) {// issue gcode #109 && issue #149if (propertyMapping.getNestedQueryId() != null && propertyMapping.isLazy()) {return configuration.getProxyFactory().createProxy(resultObject, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);}}}return resultObject;}// 创建ResultObject对象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 (typeHandlerRegistry.hasTypeHandler(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);// 实例化ResultObject} else if (shouldApplyAutomaticMappings(resultMap, false)) {return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs, columnPrefix);}throw new ExecutorException("Do not know how to create an instance of " + resultType);}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();}}}private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);boolean foundValues = false;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)) {final Class<?> propertyType = metaObject.getSetterType(property);if (typeHandlerRegistry.hasTypeHandler(propertyType)) {// 获取propertyType、columnName对应的typeHandlerfinal TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);// 获取ResultSet根据columnName获取对应的值final Object value = typeHandler.getResult(rsw.getResultSet(), columnName);// issue #377, call setter on nullsif (value != null || configuration.isCallSettersOnNulls()) {if (value != null || !propertyType.isPrimitive()) {// 用metaObject设置Result Object的valuemetaObject.setValue(property, value);}foundValues = true;}}}}return foundValues;}public List<String> getUnmappedColumnNames(ResultMap resultMap, String columnPrefix) throws SQLException {List<String> unMappedColumnNames = unMappedColumnNamesMap.get(getMapKey(resultMap, columnPrefix));if (unMappedColumnNames == null) {loadMappedAndUnmappedColumnNames(resultMap, columnPrefix);unMappedColumnNames = unMappedColumnNamesMap.get(getMapKey(resultMap, columnPrefix));}return unMappedColumnNames;}// 获取相关table中的column namesprivate void loadMappedAndUnmappedColumnNames(ResultMap resultMap, String columnPrefix) throws SQLException {List<String> mappedColumnNames = new ArrayList<String>();List<String> unmappedColumnNames = new ArrayList<String>();final String upperColumnPrefix = columnPrefix == null ? null : columnPrefix.toUpperCase(Locale.ENGLISH);final Set<String> mappedColumns = prependPrefixes(resultMap.getMappedColumns(), upperColumnPrefix);for (String columnName : columnNames) {final String upperColumnName = columnName.toUpperCase(Locale.ENGLISH);if (mappedColumns.contains(upperColumnName)) {mappedColumnNames.add(upperColumnName);} else {unmappedColumnNames.add(columnName);}}mappedColumnNamesMap.put(getMapKey(resultMap, columnPrefix), mappedColumnNames);unMappedColumnNamesMap.put(getMapKey(resultMap, columnPrefix), unmappedColumnNames);}/** ResultSetWrapper.java */public TypeHandler<?> getTypeHandler(Class<?> propertyType, String columnName) {TypeHandler<?> handler = null;Map<Class<?>, TypeHandler<?>> columnHandlers = typeHandlerMap.get(columnName);if (columnHandlers == null) {columnHandlers = new HashMap<Class<?>, TypeHandler<?>>();typeHandlerMap.put(columnName, columnHandlers);} else {handler = columnHandlers.get(propertyType);}if (handler == null) {handler = typeHandlerRegistry.getTypeHandler(propertyType);// Replicate logic of UnknownTypeHandler#resolveTypeHandler// See issue #59 comment 10if (handler == null || handler instanceof UnknownTypeHandler) {final int index = columnNames.indexOf(columnName);final JdbcType jdbcType = jdbcTypes.get(index);final Class<?> javaType = resolveClass(classNames.get(index));if (javaType != null && jdbcType != null) {handler = typeHandlerRegistry.getTypeHandler(javaType, jdbcType);} else if (javaType != null) {handler = typeHandlerRegistry.getTypeHandler(javaType);} else if (jdbcType != null) {handler = typeHandlerRegistry.getTypeHandler(jdbcType);}}if (handler == null || handler instanceof UnknownTypeHandler) {handler = new ObjectTypeHandler();}columnHandlers.put(propertyType, handler);}return handler;}/** BaseTypeHandler<T>.java */public T getResult(ResultSet rs, String columnName) throws SQLException {T result;try {result = getNullableResult(rs, columnName);} catch (Exception e) {throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e, e);}if (rs.wasNull()) {return null;} else {return result;}}/** StringTypeHandler.java */public String getNullableResult(ResultSet rs, String columnName)  throws SQLException {return rs.getString(columnName);}/** DefaultResultSetHandler.java */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 itcolumn = 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 optionalfinal String property = propertyMapping.getProperty();// issue #377, call setter on nullsif (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 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);}}private void callResultHandler(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue) {resultContext.nextResultObject(rowValue);((ResultHandler<Object>)resultHandler).handleResult(resultContext);}/** DefaultResultHandler.java */public void handleResult(ResultContext<? extends Object> context) {list.add(context.getResultObject());}/** DefaultResultSetHandler.java */private List<Object> collapseSingleResultList(List<Object> multipleResults) {return multipleResults.size() == 1 ? (List<Object>) multipleResults.get(0) : multipleResults;}

0 0
原创粉丝点击