此时咱们已经能够把整段的SQL语句取出,但还并无在数据库中去执行,咱们能够先来分析一下配置文件中SQL语句执行后的结果集是如何处理的。java
Mybatis会将结果集按照映射配置文件中定义的映射规则,例如<resultMap>,resultType属性等,映射成相应的结果对象。mysql
在StatementHandler接口执行完指定的select语句以后,会将查询获得的结果集交给ResultSetHandler完成映射处理。ResultSetHandler除了负责映射select语句查询获得的结果集,还会处理存储过程执行后的输出参数。ResultSetHandler是一个接口,定义以下sql
public interface ResultSetHandler { //处理结果集,生成相应的结果对象集合 <E> List<E> handleResultSets(Statement stmt) throws SQLException; //处理结果集,返回相应的游标对象 <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException; //处理存储过程的输出参数 void handleOutputParameters(CallableStatement cs) throws SQLException; }
ResultSetHandler只有一个实现类DefaultResultSetHandler,其核心字段以下数据库
private final Executor executor; //执行器对象 private final Configuration configuration; //全局配置信息对象 private final MappedStatement mappedStatement; //记录了SQL语句节点全部信息的对象(<select><insert><update>节点等) private final RowBounds rowBounds; //逻辑分页对象(不一样于SQL语句中的limit物理分页) private final ParameterHandler parameterHandler; //参数处理器 private final ResultHandler<?> resultHandler; //用户指定用于处理结果集的ResultHandler对象 private final BoundSql boundSql; //SqlSource执行后返回的包含完整SQL语句的对象 private final TypeHandlerRegistry typeHandlerRegistry; //类型处理器注册器 private final ObjectFactory objectFactory; //对象工厂 private final ReflectorFactory reflectorFactory; //反射工厂
private final Map<CacheKey, Object> nestedResultObjects = new HashMap<CacheKey, Object>(); //嵌套的resultMap对象映射
private Object previousRowValue; //上一次嵌套的resultMap对象
//PendingRelation是DefaultResultSetHandler的内部静态类,记录了当前结果对象对应的MetaObject对象以及parentMapping对象 //该对象就为CacheKey对象跟所有的PendingRelation对象的映射 private final Map<CacheKey, List<PendingRelation>> pendingRelations = new HashMap<CacheKey, List<PendingRelation>>();
经过select语句查询数据库获得的结果集由其handlerResultSets()方法进行处理。该方法不只能够处理Statement,PreparedStatement产生的结果集,还能够处理CallableStatement调用存储过程产生的多结果集。例如以下存储过程,就会产生多个ResultSet对象。数组
CREATE PROCEDURE test_proc()mybatis
BEGINapp
select * from persion;ide
select * from item;ui
END;this
handleResultSets()方法以下
@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; //获取第一个ResultSet对象,可能存在多个ResultSet ResultSetWrapper rsw = getFirstResultSet(stmt); //获取MappedStatement.resultMaps集合,映射文件中的<resultMap>节点会被解析成ResultMap对象,保存到MappedStatement.resultMaps集合中 //若是SQL节点可以产生多个ResultSet,那么咱们能够在SQL节点的resultMap属性中配置多个<resultMap>节点的id,它们之间经过","分隔,实现对多个 //结果集的映射 List<ResultMap> resultMaps = mappedStatement.getResultMaps(); int resultMapCount = resultMaps.size(); //若是结果集不为null,则resultMaps集合(List)不能为空,不然抛出异常 validateResultMapsCount(rsw, resultMapCount); //遍历resultMaps集合 while (rsw != null && resultMapCount > resultSetCount) { //取出resultMaps集合中的每个ResultMap对象 ResultMap resultMap = resultMaps.get(resultSetCount); handleResultSet(rsw, resultMap, multipleResults, null); rsw = getNextResultSet(stmt); 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); }
private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException { //Statement是JDBC数据操做的接口,由Connection链接数据库后建立,由各类不一样的数据库驱动来建立实现类,因为咱们项目最近使用的是mysql 8版本的数据库,它的实现类已经跟 //以往的mysql版本大不相同,此处为获取结果集 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) //检测是否还有待处理的ResultSet if (stmt.getMoreResults()) { rs = stmt.getResultSet(); } else { if (stmt.getUpdateCount() == -1) { //没有待处理的ResultSet // no more results. Must be no resultset break; } } } //将结果集封装成ResultSetWrapper对象 return rs != null ? new ResultSetWrapper(rs, configuration) : null; }
private void validateResultMapsCount(ResultSetWrapper rsw, int resultMapCount) { 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."); } }
private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException { try { //若是ResultMapping对象不为null 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()); } }
public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException { //该resultMap是否存在嵌套 if (resultMap.hasNestedResultMaps()) { //肯定没有分页,不然抛出异常 ensureNoRowBounds(); //肯定没有结果集处理器,不然抛出异常 checkResultHandler(); handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping); } else { handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping); } }
private void ensureNoRowBounds() { 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."); } }
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); //获取上一次嵌套的resultMap对象 Object rowValue = previousRowValue; //若是已处理的结果集还未到达上限且结果集中还有能够处理的记录,进入循环 while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) { //获取全部嵌套中的最终resultMap对象 final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null); //将该resultMap对象中的元素构建成CacheKey对象 final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null); //从嵌套的resultMap映射中查找该CacheKey对象映射的resultMap对象 Object partialObject = nestedResultObjects.get(rowKey); //若是<select>标签嵌套或者分组了 if (mappedStatement.isResultOrdered()) { //若是嵌套映射中没有该resultMap对象且上一次嵌套的resultMap对象不为null if (partialObject == null && rowValue != null) { //清空嵌套resultMap映射 nestedResultObjects.clear(); // storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet()); } rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject); } else { rowValue = getRowValue(rsw, discriminatedResultMap, 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()); previousRowValue = null; } else if (rowValue != null) { previousRowValue = rowValue; } }
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 { //依次访问结果集直到分页对象的偏移量处 for (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 { //记录已经处理过的ResultMap的id Set<String> pastDiscriminators = new HashSet<String>(); //获取<resultMap>中的<discriminator>节点对象,discriminator是一个鉴别器节点,如下有关于鉴别器节点的说明 Discriminator discriminator = resultMap.getDiscriminator(); //当该鉴别器对象不为null时,进入循环 while (discriminator != null) { //获取记录中对应列的值,其中会使用相应的类型处理器对象将该列值转换成java类型 final Object value = getDiscriminatorValue(rs, discriminator, columnPrefix); //根据该列值获取对应的ResultMap的id,由于这里是处理嵌套的状况,因此在<discriminator>节点下又有<resultMap>节点,若是不嵌套就通常是 //<result>或者<id>节点 final String discriminatedMapId = discriminator.getMapIdFor(String.valueOf(value)); //查找全局配置信息中是否有该嵌套的resultMap节点的id if (configuration.hasResultMap(discriminatedMapId)) { //若是有该id,根据该id在全局配置信息中获取该resultMap对象 resultMap = configuration.getResultMap(discriminatedMapId); //记录当前鉴别器对象 Discriminator lastDiscriminator = discriminator; //获取resultMap对象中的鉴别器对象 discriminator = resultMap.getDiscriminator(); //检测鉴别器是否出现了环形引用 if (discriminator == lastDiscriminator || !pastDiscriminators.add(discriminatedMapId)) { break; } } else { break; } } //返回全部嵌套中最终的使用的resultMap return resultMap; }
鉴别器节点的说明
<!-- =======================鉴别器============================ -->
<!-- <discriminator javaType=""></discriminator>
鉴别器:mybatis可使用discriminator判断某列的值,而后根据某列的值改变封装行为
封装Employee:
若是查出的是女生:就把部门信息查询出来,不然不查询;
若是是男生,把last_name这一列的值赋值给email;
-->
<resultMap type="com.mybatis.bean.Employee" id="MyEmpDis">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!--
column:指定断定的列名
javaType:列值对应的java类型 -->
<discriminator javaType="string" column="gender">
<!--女生 resultType:指定封装的结果类型;不能缺乏。/resultMap-->
<case value="0" resultType="com.atguigu.mybatis.bean.Employee">
<association property="dept"
select="com.mybatis.dao.DepartmentMapper.getDeptById"
column="d_id">
</association>
</case>
<!--男生 ;若是是男生,把last_name这一列的值赋值给email; -->
<case value="1" resultType="com.mybatis.bean.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="last_name" property="email"/>
<result column="gender" property="gender"/>
</case>
</discriminator>
</resultMap>
private Object getDiscriminatorValue(ResultSet rs, Discriminator discriminator, String columnPrefix) throws SQLException { //获取鉴别器的resultMapping对象 final ResultMapping resultMapping = discriminator.getResultMapping(); //获取resultMapping对象的类型处理器对象 final TypeHandler<?> typeHandler = resultMapping.getTypeHandler(); //使用类型处理器来处理从所有结果集中获取columnPrefix+resultMapping.getColumn()为列名的Java对象 return typeHandler.getResult(rs, prependPrefix(resultMapping.getColumn(), columnPrefix)); }
private String prependPrefix(String columnName, String prefix) { if (columnName == null || columnName.length() == 0 || prefix == null || prefix.length() == 0) { return columnName; } return prefix + columnName; }
private CacheKey createRowKey(ResultMap resultMap, ResultSetWrapper rsw, String columnPrefix) throws SQLException { //建立CacheKey对象 final CacheKey cacheKey = new CacheKey(); //将resultMap的id做为Cachekey对象的一部分 cacheKey.update(resultMap.getId()); //查找ResultMapping对象集合 List<ResultMapping> resultMappings = getResultMappingsForRowKey(resultMap); //若是该ResultMapping对象集合为空 if (resultMappings.isEmpty()) { //若是ResultMap对象为Map接口的实现类 if (Map.class.isAssignableFrom(resultMap.getType())) { //由结果集中的全部列名以及当前记录行的全部列值一块儿构成CacheKey对象 createRowKeyForMap(rsw, cacheKey); //若是ResultMap对象不是Map接口的实现类 } else { //由结果集中未映射的列名以及它们在当前记录中的对应列值一块儿构成CacheKey对象 createRowKeyForUnmappedProperties(resultMap, rsw, cacheKey, columnPrefix); } //若是该ResultMapping对象集合不为空 } else { //由resultMappings集合中的列名以及它们在当前记录行中相应的列值一块儿构成CacheKey createRowKeyForMappedProperties(resultMap, rsw, cacheKey, resultMappings, columnPrefix); } //若是经过上面的查找没有找到任何列参与构成CacheKey对象,则返回NULL_CACHE_KEY对象 if (cacheKey.getUpdateCount() < 2) { return CacheKey.NULL_CACHE_KEY; } return cacheKey; }
private List<ResultMapping> getResultMappingsForRowKey(ResultMap resultMap) { //从resultMap对象中获取idResultMappings集合,该集合记录<idArg>、<id>节点对应的ResultMapping对象 List<ResultMapping> resultMappings = resultMap.getIdResultMappings(); //若是该集合为空 if (resultMappings.isEmpty()) { //获取resultMap对象中记录了除<id*>节点以外的ResultMapping对象 resultMappings = resultMap.getPropertyResultMappings(); } return resultMappings; }
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); //若是该值不为null if (value != null) { //将列名与值分别做为cacheKey的一部分 cacheKey.update(columnName); cacheKey.update(value); } } }
private void createRowKeyForUnmappedProperties(ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, String columnPrefix) throws SQLException { //获取resultMap对象的反射原类型对象(包含类全部的方法,属性,构造器等等) 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; } } //若是ResultMap类中有该属性 if (metaType.findProperty(property, configuration.isMapUnderscoreToCamelCase()) != null) { //从结果集中获取该列名对应的值 String value = rsw.getResultSet().getString(column); //若是该值不为null if (value != null) { //将列名与值分别做为cacheKey的一部分 cacheKey.update(column); cacheKey.update(value); } } } }
private void createRowKeyForMappedProperties(ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, List<ResultMapping> resultMappings, String columnPrefix) throws SQLException { //遍历resultMappings集合 for (ResultMapping resultMapping : resultMappings) { //若是resultMapping对象获取的嵌套ResultMap的id不为null而获取的结果集为null if (resultMapping.getNestedResultMapId() != null && resultMapping.getResultSet() == null) { // Issue #392 //从全局配置信息中获取该id对应的ResultMap对象 final ResultMap nestedResultMap = configuration.getResultMap(resultMapping.getNestedResultMapId()); //递归该嵌套ResultMap对象 createRowKeyForMappedProperties(nestedResultMap, rsw, cacheKey, nestedResultMap.getConstructorResultMappings(), prependPrefix(resultMapping.getColumnPrefix(), columnPrefix)); //若是resultMapping对象的嵌套查询id为null } else if (resultMapping.getNestedQueryId() == null) { //拼装columnPrefix+resultMapping.getColumn()为column字符串 final String column = prependPrefix(resultMapping.getColumn(), columnPrefix); //获取resultMapping的类型处理器对象 final TypeHandler<?> th = resultMapping.getTypeHandler(); //获取结果集的映射列名集合 List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix); // Issue #114 //若是column不为null且列名集合中包含转换为大写的column if (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH))) { //经过类型处理器获取结果集中该column对应的Java对象(值) final Object value = th.getResult(rsw.getResultSet(), column); //若是该值不为null或者全局配置信息中容许返回空实例 if (value != null || configuration.isReturnInstanceForEmptyRow()) { //将列名与值分别做为cacheKey的一部分 cacheKey.update(column); cacheKey.update(value); } } } } }
private void storeObject(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue, ResultMapping parentMapping, ResultSet rs) throws SQLException { //若是上一层的ResultMapping对象不为null if (parentMapping != null) { //将嵌套对象记录到外层元对象相应的属性中 linkToParents(rs, parentMapping, rowValue); //若是上一层的ResultMapping对象为null } else { callResultHandler(resultHandler, resultContext, rowValue); } }
假设有这么一段resultMap
<resultMap id="blogResult" type="Blog">
<id property="id" column="id" />
<result property="title" column="title"/>
<association property="author" javaType="Author" resultSet="authors" column="author_id" foreignColumn="id">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="email" column="email"/>
<result property="bio" column="bio"/>
</association>
</resultMap>
private void linkToParents(ResultSet rs, ResultMapping parentMapping, Object rowValue) throws SQLException { //将外键对应结果集中的对象以及嵌套列名绑定到CacheKey对象中 CacheKey parentKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(), parentMapping.getForeignColumn()); //获取该CacheKey对象对应的PendingRelation列表 List<PendingRelation> parents = pendingRelations.get(parentKey); //若是该列表不为null if (parents != null) { //遍历该列表 for (PendingRelation parent : parents) { //若是列表中的每一项不为null且上一次嵌套的resultMap对象也不为null if (parent != null && rowValue != null) { //将上一层嵌套的resultMap对象放入元数据类型对象的相应属性中,若是为集合则在集合属性中添加该rowValue;若是不为集合,则直接将该属性设置为rowValue linkObjects(parent.metaObject, parent.propertyMapping, rowValue); } } } }
private CacheKey createKeyForMultipleResults(ResultSet rs, ResultMapping resultMapping, String names, String columns) throws SQLException { //新建CacheKey对象 CacheKey cacheKey = new CacheKey(); //将resultMapping对象绑定到cachekey中 cacheKey.update(resultMapping); //若是该resultMapping的ForeignColumn属性和Column属性都不为null if (columns != null && names != null) { //以","为分隔符截取ForeignColumn为字符串数组 String[] columnsArray = columns.split(","); //以","为分隔符截取Clounmn为字符串数组 String[] namesArray = names.split(","); //遍历ForeignColumn字符串数组 for (int i = 0; i < columnsArray.length; i++) { //获取字符串数组中的每一项在结果集中对象 Object value = rs.getString(columnsArray[i]); //若是该对象不为null if (value != null) { //将Columns字符串数组中的每一项以及ForeignColumns中每一项对应结果集中的对象绑定到cachekey中 cacheKey.update(namesArray[i]); cacheKey.update(value); } } } return cacheKey; }
private void linkObjects(MetaObject metaObject, ResultMapping resultMapping, Object rowValue) { //检查上一层的resultMapping是否为集合,若是为集合则进行实例化返回 final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); //若是返回的集合对象不为null if (collectionProperty != null) { //根据该集合对象在全局配置信息中生成元数据类型对象 final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty); //元数据类型对象的对象包装器属性(集合)中添加上一层的resultMap对象 targetMetaObject.add(rowValue); } else { //若是返回的集合对象为null,表示resultMapping对象不为集合,直接将上一层的resultMap对象设置进元数据对象的resultMapping.getProperty()属性中 metaObject.setValue(resultMapping.getProperty(), rowValue); } }
private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) { //获取resultMapping对象的Property属性 final String propertyName = resultMapping.getProperty(); //从metaObject中获取resultMapping对象所对应的Java对象中该属性的值(metaObject与metaClass不一样,metaClass保存了类的全部属性,方法;metaObject保存了对象全部属性 //的值) Object propertyValue = metaObject.getValue(propertyName); //若是该值为null if (propertyValue == null) { //获取resultMapping对象的Java类实例 Class<?> type = resultMapping.getJavaType(); //若是该类实例为null(在配置文件中没写) if (type == null) { //从metaObject中获取该属性的Java类实例 type = metaObject.getSetterType(propertyName); } try { //若是该java类实例为一个集合类型 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); } //若是该值不为null,且该值的类实例为集合类型 } else if (objectFactory.isCollection(propertyValue.getClass())) { //返回该值 return propertyValue; } return null; }
private void callResultHandler(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue) { resultContext.nextResultObject(rowValue); ((ResultHandler<Object>) resultHandler).handleResult(resultContext); }
在DefaultObjectFactory中
@Override public <T> boolean isCollection(Class<T> type) { //返回type是不是Collection接口的实现类或子接口 return Collection.class.isAssignableFrom(type); }
@Override public <T> T create(Class<T> type) { return create(type, null, null); }
@SuppressWarnings("unchecked") @Override public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { //获取接口的实现类实例 Class<?> classToCreate = resolveInterface(type); //返回该接口的实现类的实例化对象 return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs); }
protected Class<?> resolveInterface(Class<?> type) { //实现类 Class<?> classToCreate; //若是该接口为List,Collection,Iterable if (type == List.class || type == Collection.class || type == Iterable.class) { //实现类定为ArrayList classToCreate = ArrayList.class; //若是该接口为Map } else if (type == Map.class) { //实现类定为HashMap classToCreate = HashMap.class; //若是该接口为SortedSet } else if (type == SortedSet.class) { // issue #510 Collections Support //实现类定为TreeSet classToCreate = TreeSet.class; //若是接口为Set } else if (type == Set.class) { //实现类定为HashSet classToCreate = HashSet.class; //若是不是集合接口 } else { //直接获取该类 classToCreate = type; } return classToCreate; }
private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { try { //定义构造器 Constructor<T> constructor; //若是构造参数类型列表或者构造参数对象列表为null if (constructorArgTypes == null || constructorArgs == null) { //获取该类实例的无参构造器 constructor = type.getDeclaredConstructor(); //若是该构造器没有私有成员访问标志 if (!constructor.isAccessible()) { //设置该构造器能够访问私有成员 constructor.setAccessible(true); } //返回该构造器进行无参构造的对象实例 return constructor.newInstance(); } //若是构造参数类型列表或者构造参数对象列表不全为null,获取该类实例的以构造参数类型列表为构造参数的有参构造器 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()])); if (!constructor.isAccessible()) { constructor.setAccessible(true); } //返回该构造器进行有参构造的对象实例 return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()])); } catch (Exception e) { //异常处理 StringBuilder argTypes = new StringBuilder(); if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) { for (Class<?> argType : constructorArgTypes) { argTypes.append(argType.getSimpleName()); argTypes.append(","); } argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing , } StringBuilder argValues = new StringBuilder(); if (constructorArgs != null && !constructorArgs.isEmpty()) { for (Object argValue : constructorArgs) { argValues.append(String.valueOf(argValue)); argValues.append(","); } argValues.deleteCharAt(argValues.length() - 1); // remove trailing , } throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e); } }