Skip to content

Commit 599dcf9

Browse files
committed
#574 Merged into 3.3.x branch
1 parent ff8db5c commit 599dcf9

File tree

1 file changed

+61
-25
lines changed

1 file changed

+61
-25
lines changed

src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,27 @@ public class DefaultResultSetHandler implements ResultSetHandler {
8686
private final Map<String, ResultMapping> nextResultMaps = new HashMap<String, ResultMapping>();
8787
private final Map<CacheKey, List<PendingRelation>> pendingRelations = new HashMap<CacheKey, List<PendingRelation>>();
8888

89+
// Cached Automappings
90+
private final Map<String, List<UnMappedColumAutoMapping>> autoMappingsCache = new HashMap<String, List<UnMappedColumAutoMapping>>();
91+
8992
private static class PendingRelation {
9093
public MetaObject metaObject;
9194
public ResultMapping propertyMapping;
9295
}
9396

97+
private static class UnMappedColumAutoMapping {
98+
private final String column;
99+
private final String property;
100+
private final TypeHandler<?> typeHandler;
101+
private final boolean primitive;
102+
public UnMappedColumAutoMapping(String column, String property, TypeHandler<?> typeHandler, boolean primitive) {
103+
this.column = column;
104+
this.property = property;
105+
this.typeHandler = typeHandler;
106+
this.primitive = primitive;
107+
}
108+
}
109+
94110
public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler<?> resultHandler, BoundSql boundSql,
95111
RowBounds rowBounds) {
96112
this.executor = executor;
@@ -416,33 +432,49 @@ private Object getPropertyMappingValue(ResultSet rs, MetaObject metaResultObject
416432
}
417433
}
418434

419-
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
420-
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
421-
boolean foundValues = false;
422-
for (String columnName : unmappedColumnNames) {
423-
String propertyName = columnName;
424-
if (columnPrefix != null && !columnPrefix.isEmpty()) {
425-
// When columnPrefix is specified,
426-
// ignore columns without the prefix.
427-
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
428-
propertyName = columnName.substring(columnPrefix.length());
429-
} else {
430-
continue;
435+
private List<UnMappedColumAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
436+
final String mapKey = getMapKey(resultMap, columnPrefix);
437+
List<UnMappedColumAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
438+
if (autoMapping == null) {
439+
autoMapping = new ArrayList<UnMappedColumAutoMapping>();
440+
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
441+
for (String columnName : unmappedColumnNames) {
442+
String propertyName = columnName;
443+
if (columnPrefix != null && !columnPrefix.isEmpty()) {
444+
// When columnPrefix is specified,
445+
// ignore columns without the prefix.
446+
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
447+
propertyName = columnName.substring(columnPrefix.length());
448+
} else {
449+
continue;
450+
}
451+
}
452+
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
453+
if (property != null && metaObject.hasSetter(property)) {
454+
final Class<?> propertyType = metaObject.getSetterType(property);
455+
if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
456+
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
457+
autoMapping.add(new UnMappedColumAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
458+
}
431459
}
432460
}
433-
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
434-
if (property != null && metaObject.hasSetter(property)) {
435-
final Class<?> propertyType = metaObject.getSetterType(property);
436-
if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
437-
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
438-
final Object value = typeHandler.getResult(rsw.getResultSet(), columnName);
439-
// issue #377, call setter on nulls
440-
if (value != null || configuration.isCallSettersOnNulls()) {
441-
if (value != null || !propertyType.isPrimitive()) {
442-
metaObject.setValue(property, value);
443-
}
444-
foundValues = true;
461+
autoMappingsCache.put(mapKey, autoMapping);
462+
}
463+
return autoMapping;
464+
}
465+
466+
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
467+
List<UnMappedColumAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
468+
boolean foundValues = false;
469+
if (autoMapping.size() > 0) {
470+
for (UnMappedColumAutoMapping mapping : autoMapping) {
471+
final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
472+
// issue #377, call setter on nulls
473+
if (value != null || configuration.isCallSettersOnNulls()) {
474+
if (value != null || !mapping.primitive) {
475+
metaObject.setValue(mapping.property, value);
445476
}
477+
foundValues = true;
446478
}
447479
}
448480
}
@@ -1015,6 +1047,10 @@ private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMa
10151047
return propertyValue;
10161048
}
10171049
return null;
1018-
}
1050+
}
10191051

1052+
private String getMapKey(ResultMap resultMap, String columnPrefix) {
1053+
return resultMap.getId() + ":" + columnPrefix;
1054+
}
1055+
10201056
}

0 commit comments

Comments
 (0)