1515 */
1616package org .apache .ibatis .session ;
1717
18+ import java .sql .SQLException ;
1819import java .util .Arrays ;
1920import java .util .Collection ;
2021import java .util .HashMap ;
2324import java .util .LinkedList ;
2425import java .util .List ;
2526import java .util .Map ;
27+ import java .util .Objects ;
2628import java .util .Properties ;
2729import java .util .Set ;
2830import java .util .concurrent .ConcurrentHashMap ;
6971import org .apache .ibatis .logging .slf4j .Slf4jImpl ;
7072import org .apache .ibatis .logging .stdout .StdOutImpl ;
7173import org .apache .ibatis .mapping .BoundSql ;
74+ import org .apache .ibatis .mapping .DatabaseIdProvider ;
7275import org .apache .ibatis .mapping .Environment ;
7376import org .apache .ibatis .mapping .MappedStatement ;
7477import org .apache .ibatis .mapping .ParameterMap ;
@@ -108,6 +111,7 @@ public class Configuration {
108111 protected boolean safeResultHandlerEnabled = true ;
109112 protected boolean mapUnderscoreToCamelCase ;
110113 protected boolean aggressiveLazyLoading ;
114+ protected boolean multipleResultSetsEnabled = true ;
111115 protected boolean useGeneratedKeys ;
112116 protected boolean useColumnLabel = true ;
113117 protected boolean cacheEnabled = true ;
@@ -117,6 +121,7 @@ public class Configuration {
117121 protected boolean shrinkWhitespacesInSql ;
118122 protected boolean nullableOnForEach ;
119123 protected boolean argNameBasedConstructorAutoMapping ;
124+ protected boolean supportDynamicRoutingDataSource ;
120125
121126 protected String logPrefix ;
122127 protected Class <? extends Log > logImpl ;
@@ -133,6 +138,7 @@ public class Configuration {
133138 protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior .PARTIAL ;
134139 protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior .NONE ;
135140
141+ protected DatabaseIdProvider databaseIdProvider ;
136142 protected Properties variables = new Properties ();
137143 protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory ();
138144 protected ObjectFactory objectFactory = new DefaultObjectFactory ();
@@ -349,6 +355,29 @@ public void setDatabaseId(String databaseId) {
349355 this .databaseId = databaseId ;
350356 }
351357
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+
352381 public Class <?> getConfigurationFactory () {
353382 return configurationFactory ;
354383 }
@@ -455,20 +484,12 @@ public void setAggressiveLazyLoading(boolean aggressiveLazyLoading) {
455484 this .aggressiveLazyLoading = aggressiveLazyLoading ;
456485 }
457486
458- /**
459- * @deprecated You can safely remove the call to this method as this option had no effect.
460- */
461- @ Deprecated
462487 public boolean isMultipleResultSetsEnabled () {
463- return true ;
488+ return multipleResultSetsEnabled ;
464489 }
465490
466- /**
467- * @deprecated You can safely remove the call to this method as this option had no effect.
468- */
469- @ Deprecated
470491 public void setMultipleResultSetsEnabled (boolean multipleResultSetsEnabled ) {
471- // nop
492+ this . multipleResultSetsEnabled = multipleResultSetsEnabled ;
472493 }
473494
474495 public Set <String > getLazyLoadTriggerMethods () {
@@ -831,7 +852,11 @@ public boolean hasParameterMap(String id) {
831852 }
832853
833854 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 );
835860 }
836861
837862 public Collection <String > getMappedStatementNames () {
@@ -920,7 +945,22 @@ public MappedStatement getMappedStatement(String id, boolean validateIncompleteS
920945 if (validateIncompleteStatements ) {
921946 buildAllStatements ();
922947 }
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 ;
924964 }
925965
926966 public Map <String , XNode > getSqlFragments () {
@@ -959,7 +999,8 @@ public boolean hasStatement(String statementName, boolean validateIncompleteStat
959999 if (validateIncompleteStatements ) {
9601000 buildAllStatements ();
9611001 }
962- return mappedStatements .containsKey (statementName );
1002+ return mappedStatements .containsKey (this .getMappedStatementId (statementName ))
1003+ || this .getSupportDynamicRoutingDataSource () && mappedStatements .containsKey (statementName );
9631004 }
9641005
9651006 public void addCacheRef (String namespace , String referencedNamespace ) {
@@ -1113,7 +1154,6 @@ protected static class StrictMap<V> extends ConcurrentHashMap<String, V> {
11131154 private static final long serialVersionUID = -4950446264854982944L ;
11141155 private final String name ;
11151156 private BiFunction <V , V , String > conflictMessageProducer ;
1116- private static final Object AMBIGUITY_INSTANCE = new Object ();
11171157
11181158 public StrictMap (String name , int initialCapacity , float loadFactor ) {
11191159 super (initialCapacity , loadFactor );
@@ -1163,7 +1203,7 @@ public V put(String key, V value) {
11631203 if (super .get (shortKey ) == null ) {
11641204 super .put (shortKey , value );
11651205 } else {
1166- super .put (shortKey , (V ) AMBIGUITY_INSTANCE );
1206+ super .put (shortKey , (V ) new Ambiguity ( shortKey ) );
11671207 }
11681208 }
11691209 return super .put (key , value );
@@ -1184,13 +1224,25 @@ public V get(Object key) {
11841224 if (value == null ) {
11851225 throw new IllegalArgumentException (name + " does not contain value for " + key );
11861226 }
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
11891229 + " (try using the full name including the namespace, or rename one of the entries)" );
11901230 }
11911231 return value ;
11921232 }
11931233
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+
11941246 private String getShortName (String key ) {
11951247 final String [] keyParts = key .split ("\\ ." );
11961248 return keyParts [keyParts .length - 1 ];
0 commit comments