Skip to content

Commit 340802b

Browse files
committed
Cached Automatic Mappings
1 parent 905ff79 commit 340802b

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
@@ -88,11 +88,27 @@ public class DefaultResultSetHandler implements ResultSetHandler {
8888
private final Map<String, ResultMapping> nextResultMaps = new HashMap<String, ResultMapping>();
8989
private final Map<CacheKey, List<PendingRelation>> pendingRelations = new HashMap<CacheKey, List<PendingRelation>>();
9090

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

99+
private static class UnMappedColumAutoMapping {
100+
private final String column;
101+
private final String property;
102+
private final TypeHandler<?> typeHandler;
103+
private final boolean primitive;
104+
public UnMappedColumAutoMapping(String column, String property, TypeHandler<?> typeHandler, boolean primitive) {
105+
this.column = column;
106+
this.property = property;
107+
this.typeHandler = typeHandler;
108+
this.primitive = primitive;
109+
}
110+
}
111+
96112
public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler<?> resultHandler, BoundSql boundSql,
97113
RowBounds rowBounds) {
98114
this.executor = executor;
@@ -433,33 +449,49 @@ private Object getPropertyMappingValue(ResultSet rs, MetaObject metaResultObject
433449
}
434450
}
435451

436-
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
437-
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
438-
boolean foundValues = false;
439-
for (String columnName : unmappedColumnNames) {
440-
String propertyName = columnName;
441-
if (columnPrefix != null && !columnPrefix.isEmpty()) {
442-
// When columnPrefix is specified,
443-
// ignore columns without the prefix.
444-
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
445-
propertyName = columnName.substring(columnPrefix.length());
446-
} else {
447-
continue;
452+
private List<UnMappedColumAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
453+
final String mapKey = getMapKey(resultMap, columnPrefix);
454+
List<UnMappedColumAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
455+
if (autoMapping == null) {
456+
autoMapping = new ArrayList<UnMappedColumAutoMapping>();
457+
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
458+
for (String columnName : unmappedColumnNames) {
459+
String propertyName = columnName;
460+
if (columnPrefix != null && !columnPrefix.isEmpty()) {
461+
// When columnPrefix is specified,
462+
// ignore columns without the prefix.
463+
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
464+
propertyName = columnName.substring(columnPrefix.length());
465+
} else {
466+
continue;
467+
}
468+
}
469+
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
470+
if (property != null && metaObject.hasSetter(property)) {
471+
final Class<?> propertyType = metaObject.getSetterType(property);
472+
if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
473+
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
474+
autoMapping.add(new UnMappedColumAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
475+
}
448476
}
449477
}
450-
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
451-
if (property != null && metaObject.hasSetter(property)) {
452-
final Class<?> propertyType = metaObject.getSetterType(property);
453-
if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
454-
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
455-
final Object value = typeHandler.getResult(rsw.getResultSet(), columnName);
456-
// issue #377, call setter on nulls
457-
if (value != null || configuration.isCallSettersOnNulls()) {
458-
if (value != null || !propertyType.isPrimitive()) {
459-
metaObject.setValue(property, value);
460-
}
461-
foundValues = true;
478+
}
479+
autoMappingsCache.put(mapKey, autoMapping);
480+
return autoMapping;
481+
}
482+
483+
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
484+
List<UnMappedColumAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
485+
boolean foundValues = false;
486+
if (autoMapping.size() > 0) {
487+
for (UnMappedColumAutoMapping mapping : autoMapping) {
488+
final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
489+
// issue #377, call setter on nulls
490+
if (value != null || configuration.isCallSettersOnNulls()) {
491+
if (value != null || !mapping.primitive) {
492+
metaObject.setValue(mapping.property, value);
462493
}
494+
foundValues = true;
463495
}
464496
}
465497
}
@@ -1037,6 +1069,10 @@ private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMa
10371069
return propertyValue;
10381070
}
10391071
return null;
1040-
}
1072+
}
10411073

1074+
private String getMapKey(ResultMap resultMap, String columnPrefix) {
1075+
return resultMap.getId() + ":" + columnPrefix;
1076+
}
1077+
10421078
}

0 commit comments

Comments
 (0)