15
15
*/
16
16
package org .apache .ibatis .session ;
17
17
18
+ import java .sql .SQLException ;
18
19
import java .util .Arrays ;
19
20
import java .util .Collection ;
20
21
import java .util .HashMap ;
23
24
import java .util .LinkedList ;
24
25
import java .util .List ;
25
26
import java .util .Map ;
27
+ import java .util .Objects ;
26
28
import java .util .Properties ;
27
29
import java .util .Set ;
28
30
import java .util .concurrent .ConcurrentHashMap ;
69
71
import org .apache .ibatis .logging .slf4j .Slf4jImpl ;
70
72
import org .apache .ibatis .logging .stdout .StdOutImpl ;
71
73
import org .apache .ibatis .mapping .BoundSql ;
74
+ import org .apache .ibatis .mapping .DatabaseIdProvider ;
72
75
import org .apache .ibatis .mapping .Environment ;
73
76
import org .apache .ibatis .mapping .MappedStatement ;
74
77
import org .apache .ibatis .mapping .ParameterMap ;
@@ -108,6 +111,7 @@ public class Configuration {
108
111
protected boolean safeResultHandlerEnabled = true ;
109
112
protected boolean mapUnderscoreToCamelCase ;
110
113
protected boolean aggressiveLazyLoading ;
114
+ protected boolean multipleResultSetsEnabled = true ;
111
115
protected boolean useGeneratedKeys ;
112
116
protected boolean useColumnLabel = true ;
113
117
protected boolean cacheEnabled = true ;
@@ -117,6 +121,7 @@ public class Configuration {
117
121
protected boolean shrinkWhitespacesInSql ;
118
122
protected boolean nullableOnForEach ;
119
123
protected boolean argNameBasedConstructorAutoMapping ;
124
+ protected boolean supportDynamicRoutingDataSource ;
120
125
121
126
protected String logPrefix ;
122
127
protected Class <? extends Log > logImpl ;
@@ -133,6 +138,7 @@ public class Configuration {
133
138
protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior .PARTIAL ;
134
139
protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior .NONE ;
135
140
141
+ protected DatabaseIdProvider databaseIdProvider ;
136
142
protected Properties variables = new Properties ();
137
143
protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory ();
138
144
protected ObjectFactory objectFactory = new DefaultObjectFactory ();
@@ -349,6 +355,29 @@ public void setDatabaseId(String databaseId) {
349
355
this .databaseId = databaseId ;
350
356
}
351
357
358
+ public boolean getSupportDynamicRoutingDataSource () {
359
+ return this .supportDynamicRoutingDataSource ;
360
+ }
361
+
362
+ public void setSupportDynamicRoutingDataSource (Boolean supportDynamicRoutingDataSource ) {
363
+ this .supportDynamicRoutingDataSource = supportDynamicRoutingDataSource ;
364
+ }
365
+
366
+ public DatabaseIdProvider getDatabaseIdProvider () {
367
+ return databaseIdProvider ;
368
+ }
369
+
370
+ public void setDatabaseIdProvider (DatabaseIdProvider databaseIdProvider ) {
371
+ this .databaseIdProvider = databaseIdProvider ;
372
+ }
373
+
374
+ public String getCurrentDatabaseId () throws SQLException {
375
+ if (supportDynamicRoutingDataSource && databaseIdProvider != null ) {
376
+ return databaseIdProvider .getDatabaseId (environment .getDataSource ());
377
+ }
378
+ return this .getDatabaseId ();
379
+ }
380
+
352
381
public Class <?> getConfigurationFactory () {
353
382
return configurationFactory ;
354
383
}
@@ -455,20 +484,12 @@ public void setAggressiveLazyLoading(boolean aggressiveLazyLoading) {
455
484
this .aggressiveLazyLoading = aggressiveLazyLoading ;
456
485
}
457
486
458
- /**
459
- * @deprecated You can safely remove the call to this method as this option had no effect.
460
- */
461
- @ Deprecated
462
487
public boolean isMultipleResultSetsEnabled () {
463
- return true ;
488
+ return multipleResultSetsEnabled ;
464
489
}
465
490
466
- /**
467
- * @deprecated You can safely remove the call to this method as this option had no effect.
468
- */
469
- @ Deprecated
470
491
public void setMultipleResultSetsEnabled (boolean multipleResultSetsEnabled ) {
471
- // nop
492
+ this . multipleResultSetsEnabled = multipleResultSetsEnabled ;
472
493
}
473
494
474
495
public Set <String > getLazyLoadTriggerMethods () {
@@ -831,7 +852,11 @@ public boolean hasParameterMap(String id) {
831
852
}
832
853
833
854
public void addMappedStatement (MappedStatement ms ) {
834
- mappedStatements .put (ms .getId (), ms );
855
+ String id = ms .getId ();
856
+ if (this .getSupportDynamicRoutingDataSource () && Objects .nonNull (ms .getDatabaseId ())) {
857
+ id = id + "#" + ms .getDatabaseId ();
858
+ }
859
+ mappedStatements .put (id , ms );
835
860
}
836
861
837
862
public Collection <String > getMappedStatementNames () {
@@ -920,7 +945,22 @@ public MappedStatement getMappedStatement(String id, boolean validateIncompleteS
920
945
if (validateIncompleteStatements ) {
921
946
buildAllStatements ();
922
947
}
923
- return mappedStatements .get (id );
948
+ MappedStatement statement = mappedStatements .get (this .getMappedStatementId (id ));
949
+ if (this .getSupportDynamicRoutingDataSource () && Objects .isNull (statement )) {
950
+ statement = mappedStatements .get (id );
951
+ }
952
+ return statement ;
953
+ }
954
+
955
+ protected String getMappedStatementId (String id ) {
956
+ try {
957
+ String databaseId = this .getCurrentDatabaseId ();
958
+ if (this .getSupportDynamicRoutingDataSource () && Objects .nonNull (databaseId )) {
959
+ return id + "#" + databaseId ;
960
+ }
961
+ } catch (SQLException ignore ) {
962
+ }
963
+ return id ;
924
964
}
925
965
926
966
public Map <String , XNode > getSqlFragments () {
@@ -959,7 +999,8 @@ public boolean hasStatement(String statementName, boolean validateIncompleteStat
959
999
if (validateIncompleteStatements ) {
960
1000
buildAllStatements ();
961
1001
}
962
- return mappedStatements .containsKey (statementName );
1002
+ return mappedStatements .containsKey (this .getMappedStatementId (statementName ))
1003
+ || this .getSupportDynamicRoutingDataSource () && mappedStatements .containsKey (statementName );
963
1004
}
964
1005
965
1006
public void addCacheRef (String namespace , String referencedNamespace ) {
@@ -1113,7 +1154,6 @@ protected static class StrictMap<V> extends ConcurrentHashMap<String, V> {
1113
1154
private static final long serialVersionUID = -4950446264854982944L ;
1114
1155
private final String name ;
1115
1156
private BiFunction <V , V , String > conflictMessageProducer ;
1116
- private static final Object AMBIGUITY_INSTANCE = new Object ();
1117
1157
1118
1158
public StrictMap (String name , int initialCapacity , float loadFactor ) {
1119
1159
super (initialCapacity , loadFactor );
@@ -1163,7 +1203,7 @@ public V put(String key, V value) {
1163
1203
if (super .get (shortKey ) == null ) {
1164
1204
super .put (shortKey , value );
1165
1205
} else {
1166
- super .put (shortKey , (V ) AMBIGUITY_INSTANCE );
1206
+ super .put (shortKey , (V ) new Ambiguity ( shortKey ) );
1167
1207
}
1168
1208
}
1169
1209
return super .put (key , value );
@@ -1184,13 +1224,25 @@ public V get(Object key) {
1184
1224
if (value == null ) {
1185
1225
throw new IllegalArgumentException (name + " does not contain value for " + key );
1186
1226
}
1187
- if (AMBIGUITY_INSTANCE == value ) {
1188
- throw new IllegalArgumentException (key + " is ambiguous in " + name
1227
+ if (value instanceof Ambiguity ) {
1228
+ throw new IllegalArgumentException ((( Ambiguity ) value ). getSubject () + " is ambiguous in " + name
1189
1229
+ " (try using the full name including the namespace, or rename one of the entries)" );
1190
1230
}
1191
1231
return value ;
1192
1232
}
1193
1233
1234
+ protected static class Ambiguity {
1235
+ private final String subject ;
1236
+
1237
+ public Ambiguity (String subject ) {
1238
+ this .subject = subject ;
1239
+ }
1240
+
1241
+ public String getSubject () {
1242
+ return subject ;
1243
+ }
1244
+ }
1245
+
1194
1246
private String getShortName (String key ) {
1195
1247
final String [] keyParts = key .split ("\\ ." );
1196
1248
return keyParts [keyParts .length - 1 ];
0 commit comments