mybatis执行流程图-ResultSetHandler接口
1. ResultSetHandler接口的实现类DefaultResultSetHandler介绍
image.png1 ) PreparedStatementHandler执行query方法,把执行后的PreparedStatement对象作为入参调用ResultSetHandler类的handleResultSets方法。
2 ) 把Statement对象作为入参调用getFirstResultSet方法返回第一条数据的ResultSetWrapper对象。
3 )调用mappedStatement.getResultMaps().size()方法获取查询结果记录的条数
4 ) 通过while循环遍历第一条数据的ResultSetWrapper对象或下一条数据的ResultSetWrapper对象,直到第一条或下一条数据为空时,即中止执行。在while循环内部获取每执行一次会调用getNextResultSet方法获取下一条数据的ResultSetWrapper对象。
5 ) 提取最终数据是通过把ResultSetWrapper对象对象作为入参,调用 handleResultSet方法完成的,提取出来的数据会存在multipleResults集合中,最终返回。
2. 结果数据的提取-handleResultSet方法
image.pngDefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
multipleResults.add(defaultResultHandler.getResultList());
3. handleRowValues方法
这里面会调handleRowValuesForSimpleResultMap方法
DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
ResultSet resultSet = rsw.getResultSet();
skipRows(resultSet, rowBounds);
while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
1 ) 通过ResultSetWrapper对象获取到单条数据的ResultSet对象,作为入参调用resolveDiscriminatedResultMap方法,最后返回ResultMap对象。
2 )把ResultMap对象作为入参调用getRowValue方法,最后返回rowValue.
3 )获取到rowValue后调用storeObject方法存入resultHandler对象中。
4. getRowValue方法
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;
}
获取单个属性源码
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);
}
}
获取值BaseTypeHandler
@Override
public T getResult(ResultSet rs, String columnName) throws SQLException {
try {
return getNullableResult(rs, columnName);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set. Cause: " + e, e);
}
}
调回IntegerTypeHandler
@Override
public Integer getNullableResult(ResultSet rs, String columnName)
throws SQLException {
int result = rs.getInt(columnName);
return result == 0 && rs.wasNull() ? null : result;
}