1
1
/**
2
- * Copyright 2009-2017 the original author or authors.
2
+ * Copyright 2009-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
45
45
import org .apache .ibatis .session .ResultContext ;
46
46
import org .apache .ibatis .session .ResultHandler ;
47
47
import org .apache .ibatis .session .RowBounds ;
48
+ import org .apache .ibatis .type .JdbcType ;
48
49
import org .apache .ibatis .type .TypeHandler ;
49
50
import org .apache .ibatis .type .TypeHandlerRegistry ;
50
51
@@ -83,22 +84,20 @@ public class DefaultResultSetHandler implements ResultSetHandler {
83
84
private final ReflectorFactory reflectorFactory ;
84
85
85
86
// nested resultmaps
86
- private final Map <CacheKey , Object > nestedResultObjects = new HashMap <CacheKey , Object >();
87
- private final Map <String , Object > ancestorObjects = new HashMap <String , Object >();
87
+ private final Map <CacheKey , Object > nestedResultObjects = new HashMap <>();
88
+ private final Map <String , Object > ancestorObjects = new HashMap <>();
88
89
private Object previousRowValue ;
89
90
90
91
// multiple resultsets
91
- private final Map <String , ResultMapping > nextResultMaps = new HashMap <String , ResultMapping >();
92
- private final Map <CacheKey , List <PendingRelation >> pendingRelations = new HashMap <CacheKey , List < PendingRelation > >();
92
+ private final Map <String , ResultMapping > nextResultMaps = new HashMap <>();
93
+ private final Map <CacheKey , List <PendingRelation >> pendingRelations = new HashMap <>();
93
94
94
95
// Cached Automappings
95
- private final Map <String , List <UnMappedColumnAutoMapping >> autoMappingsCache = new HashMap <String , List < UnMappedColumnAutoMapping > >();
96
+ private final Map <String , List <UnMappedColumnAutoMapping >> autoMappingsCache = new HashMap <>();
96
97
97
98
// temporary marking flag that indicate using constructor mapping (use field to reduce memory usage)
98
99
private boolean useConstructorMappings ;
99
100
100
- private final PrimitiveTypes primitiveTypes ;
101
-
102
101
private static class PendingRelation {
103
102
public MetaObject metaObject ;
104
103
public ResultMapping propertyMapping ;
@@ -130,7 +129,6 @@ public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatemen
130
129
this .objectFactory = configuration .getObjectFactory ();
131
130
this .reflectorFactory = configuration .getReflectorFactory ();
132
131
this .resultHandler = resultHandler ;
133
- this .primitiveTypes = new PrimitiveTypes ();
134
132
}
135
133
136
134
//
@@ -183,7 +181,7 @@ private void handleRefCursorOutputParameter(ResultSet rs, ParameterMapping param
183
181
public List <Object > handleResultSets (Statement stmt ) throws SQLException {
184
182
ErrorContext .instance ().activity ("handling results" ).object (mappedStatement .getId ());
185
183
186
- final List <Object > multipleResults = new ArrayList <Object >();
184
+ final List <Object > multipleResults = new ArrayList <>();
187
185
188
186
int resultSetCount = 0 ;
189
187
ResultSetWrapper rsw = getFirstResultSet (stmt );
@@ -232,7 +230,7 @@ public <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException
232
230
}
233
231
234
232
ResultMap resultMap = resultMaps .get (0 );
235
- return new DefaultCursor <E >(this , resultMap , rsw , rowBounds );
233
+ return new DefaultCursor <>(this , resultMap , rsw , rowBounds );
236
234
}
237
235
238
236
private ResultSetWrapper getFirstResultSet (Statement stmt ) throws SQLException {
@@ -252,7 +250,7 @@ private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException {
252
250
return rs != null ? new ResultSetWrapper (rs , configuration ) : null ;
253
251
}
254
252
255
- private ResultSetWrapper getNextResultSet (Statement stmt ) throws SQLException {
253
+ private ResultSetWrapper getNextResultSet (Statement stmt ) {
256
254
// Making this method tolerant of bad JDBC drivers
257
255
try {
258
256
if (stmt .getConnection ().getMetaData ().supportsMultipleResultSets ()) {
@@ -348,7 +346,7 @@ protected void checkResultHandler() {
348
346
349
347
private void handleRowValuesForSimpleResultMap (ResultSetWrapper rsw , ResultMap resultMap , ResultHandler <?> resultHandler , RowBounds rowBounds , ResultMapping parentMapping )
350
348
throws SQLException {
351
- DefaultResultContext <Object > resultContext = new DefaultResultContext <Object >();
349
+ DefaultResultContext <Object > resultContext = new DefaultResultContext <>();
352
350
skipRows (rsw .getResultSet (), rowBounds );
353
351
while (shouldProcessMoreRows (resultContext , rowBounds ) && rsw .getResultSet ().next ()) {
354
352
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap (rsw .getResultSet (), resultMap , null );
@@ -371,7 +369,7 @@ private void callResultHandler(ResultHandler<?> resultHandler, DefaultResultCont
371
369
((ResultHandler <Object >) resultHandler ).handleResult (resultContext );
372
370
}
373
371
374
- private boolean shouldProcessMoreRows (ResultContext <?> context , RowBounds rowBounds ) throws SQLException {
372
+ private boolean shouldProcessMoreRows (ResultContext <?> context , RowBounds rowBounds ) {
375
373
return !context .isStopped () && context .getResultCount () < rowBounds .getLimit ();
376
374
}
377
375
@@ -476,7 +474,7 @@ private List<UnMappedColumnAutoMapping> createAutomaticMappings(ResultSetWrapper
476
474
final String mapKey = resultMap .getId () + ":" + columnPrefix ;
477
475
List <UnMappedColumnAutoMapping > autoMapping = autoMappingsCache .get (mapKey );
478
476
if (autoMapping == null ) {
479
- autoMapping = new ArrayList <UnMappedColumnAutoMapping >();
477
+ autoMapping = new ArrayList <>();
480
478
final List <String > unmappedColumnNames = rsw .getUnmappedColumnNames (resultMap , columnPrefix );
481
479
for (String columnName : unmappedColumnNames ) {
482
480
String propertyName = columnName ;
@@ -549,12 +547,8 @@ private void addPendingChildRelation(ResultSet rs, MetaObject metaResultObject,
549
547
PendingRelation deferLoad = new PendingRelation ();
550
548
deferLoad .metaObject = metaResultObject ;
551
549
deferLoad .propertyMapping = parentMapping ;
552
- List <PendingRelation > relations = pendingRelations .get (cacheKey );
550
+ List <PendingRelation > relations = pendingRelations .computeIfAbsent (cacheKey , k -> new ArrayList <>() );
553
551
// issue #255
554
- if (relations == null ) {
555
- relations = new ArrayList <DefaultResultSetHandler .PendingRelation >();
556
- pendingRelations .put (cacheKey , relations );
557
- }
558
552
relations .add (deferLoad );
559
553
ResultMapping previous = nextResultMaps .get (parentMapping .getResultSet ());
560
554
if (previous == null ) {
@@ -589,8 +583,8 @@ private CacheKey createKeyForMultipleResults(ResultSet rs, ResultMapping resultM
589
583
590
584
private Object createResultObject (ResultSetWrapper rsw , ResultMap resultMap , ResultLoaderMap lazyLoader , String columnPrefix ) throws SQLException {
591
585
this .useConstructorMappings = false ; // reset previous mapping result
592
- final List <Class <?>> constructorArgTypes = new ArrayList <Class <?> >();
593
- final List <Object > constructorArgs = new ArrayList <Object >();
586
+ final List <Class <?>> constructorArgTypes = new ArrayList <>();
587
+ final List <Object > constructorArgs = new ArrayList <>();
594
588
Object resultObject = createResultObject (rsw , resultMap , constructorArgTypes , constructorArgs , columnPrefix );
595
589
if (resultObject != null && !hasTypeHandlerForResultObject (rsw , resultMap .getType ())) {
596
590
final List <ResultMapping > propertyMappings = resultMap .getPropertyResultMappings ();
@@ -655,12 +649,12 @@ Object createParameterizedResultObject(ResultSetWrapper rsw, Class<?> resultType
655
649
private Object createByConstructorSignature (ResultSetWrapper rsw , Class <?> resultType , List <Class <?>> constructorArgTypes , List <Object > constructorArgs ,
656
650
String columnPrefix ) throws SQLException {
657
651
final Constructor <?>[] constructors = resultType .getDeclaredConstructors ();
658
- final Constructor <?> annotatedConstructor = findAnnotatedConstructor (constructors );
659
- if (annotatedConstructor != null ) {
660
- return createUsingConstructor (rsw , resultType , constructorArgTypes , constructorArgs , columnPrefix , annotatedConstructor );
652
+ final Constructor <?> defaultConstructor = findDefaultConstructor (constructors );
653
+ if (defaultConstructor != null ) {
654
+ return createUsingConstructor (rsw , resultType , constructorArgTypes , constructorArgs , columnPrefix , defaultConstructor );
661
655
} else {
662
656
for (Constructor <?> constructor : constructors ) {
663
- if (allowedConstructor (constructor , rsw .getClassNames ())) {
657
+ if (allowedConstructorUsingTypeHandlers (constructor , rsw .getJdbcTypes ())) {
664
658
return createUsingConstructor (rsw , resultType , constructorArgTypes , constructorArgs , columnPrefix , constructor );
665
659
}
666
660
}
@@ -682,7 +676,9 @@ private Object createUsingConstructor(ResultSetWrapper rsw, Class<?> resultType,
682
676
return foundValues ? objectFactory .create (resultType , constructorArgTypes , constructorArgs ) : null ;
683
677
}
684
678
685
- private Constructor <?> findAnnotatedConstructor (final Constructor <?>[] constructors ) {
679
+ private Constructor <?> findDefaultConstructor (final Constructor <?>[] constructors ) {
680
+ if (constructors .length == 1 ) return constructors [0 ];
681
+
686
682
for (final Constructor <?> constructor : constructors ) {
687
683
if (constructor .isAnnotationPresent (AutomapConstructor .class )) {
688
684
return constructor ;
@@ -691,29 +687,17 @@ private Constructor<?> findAnnotatedConstructor(final Constructor<?>[] construct
691
687
return null ;
692
688
}
693
689
694
- private boolean allowedConstructor (final Constructor <?> constructor , final List <String > classNames ) {
690
+ private boolean allowedConstructorUsingTypeHandlers (final Constructor <?> constructor , final List <JdbcType > jdbcTypes ) {
695
691
final Class <?>[] parameterTypes = constructor .getParameterTypes ();
696
- if (typeNames (parameterTypes ).equals (classNames )) return true ;
697
- if (parameterTypes .length != classNames .size ()) return false ;
692
+ if (parameterTypes .length != jdbcTypes .size ()) return false ;
698
693
for (int i = 0 ; i < parameterTypes .length ; i ++) {
699
- final Class <?> parameterType = parameterTypes [i ];
700
- if (parameterType .isPrimitive () && !primitiveTypes .getWrapper (parameterType ).getName ().equals (classNames .get (i ))) {
701
- return false ;
702
- } else if (!parameterType .isPrimitive () && !parameterType .getName ().equals (classNames .get (i ))) {
694
+ if (!typeHandlerRegistry .hasTypeHandler (parameterTypes [i ], jdbcTypes .get (i ))) {
703
695
return false ;
704
696
}
705
697
}
706
698
return true ;
707
699
}
708
700
709
- private List <String > typeNames (Class <?>[] parameterTypes ) {
710
- List <String > names = new ArrayList <String >();
711
- for (Class <?> type : parameterTypes ) {
712
- names .add (type .getName ());
713
- }
714
- return names ;
715
- }
716
-
717
701
private Object createPrimitiveResultObject (ResultSetWrapper rsw , ResultMap resultMap , String columnPrefix ) throws SQLException {
718
702
final Class <?> resultType = resultMap .getType ();
719
703
final String columnName ;
@@ -813,9 +797,9 @@ private Object prepareCompositeKeyParameter(ResultSet rs, ResultMapping resultMa
813
797
814
798
private Object instantiateParameterObject (Class <?> parameterType ) {
815
799
if (parameterType == null ) {
816
- return new HashMap <Object , Object >();
800
+ return new HashMap <>();
817
801
} else if (ParamMap .class .equals (parameterType )) {
818
- return new HashMap <Object , Object >(); // issue #649
802
+ return new HashMap <>(); // issue #649
819
803
} else {
820
804
return objectFactory .create (parameterType );
821
805
}
@@ -826,7 +810,7 @@ private Object instantiateParameterObject(Class<?> parameterType) {
826
810
//
827
811
828
812
public ResultMap resolveDiscriminatedResultMap (ResultSet rs , ResultMap resultMap , String columnPrefix ) throws SQLException {
829
- Set <String > pastDiscriminators = new HashSet <String >();
813
+ Set <String > pastDiscriminators = new HashSet <>();
830
814
Discriminator discriminator = resultMap .getDiscriminator ();
831
815
while (discriminator != null ) {
832
816
final Object value = getDiscriminatorValue (rs , discriminator , columnPrefix );
@@ -863,7 +847,7 @@ private String prependPrefix(String columnName, String prefix) {
863
847
//
864
848
865
849
private void handleRowValuesForNestedResultMap (ResultSetWrapper rsw , ResultMap resultMap , ResultHandler <?> resultHandler , RowBounds rowBounds , ResultMapping parentMapping ) throws SQLException {
866
- final DefaultResultContext <Object > resultContext = new DefaultResultContext <Object >();
850
+ final DefaultResultContext <Object > resultContext = new DefaultResultContext <>();
867
851
skipRows (rsw .getResultSet (), rowBounds );
868
852
Object rowValue = previousRowValue ;
869
853
while (shouldProcessMoreRows (resultContext , rowBounds ) && rsw .getResultSet ().next ()) {
0 commit comments