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,12 @@ 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+ && ms .getDatabaseId ().trim ().length () > 0 ) {
858+ id = id + "#" + ms .getDatabaseId ();
859+ }
860+ mappedStatements .put (id , ms );
835861 }
836862
837863 public Collection <String > getMappedStatementNames () {
@@ -920,7 +946,29 @@ public MappedStatement getMappedStatement(String id, boolean validateIncompleteS
920946 if (validateIncompleteStatements ) {
921947 buildAllStatements ();
922948 }
923- return mappedStatements .get (id );
949+ MappedStatement statement = null ;
950+ try {
951+ statement = mappedStatements .get (this .getMappedStatementId (id ));
952+ } catch (IllegalArgumentException e ) {
953+ if (this .getSupportDynamicRoutingDataSource ()) {
954+ statement = mappedStatements .get (id );
955+ } else {
956+ throw e ;
957+ }
958+ }
959+
960+ return statement ;
961+ }
962+
963+ protected String getMappedStatementId (String id ) {
964+ try {
965+ String databaseId = this .getCurrentDatabaseId ();
966+ if (this .getSupportDynamicRoutingDataSource () && Objects .nonNull (databaseId )) {
967+ return id + "#" + databaseId ;
968+ }
969+ } catch (SQLException ignore ) {
970+ }
971+ return id ;
924972 }
925973
926974 public Map <String , XNode > getSqlFragments () {
@@ -959,7 +1007,8 @@ public boolean hasStatement(String statementName, boolean validateIncompleteStat
9591007 if (validateIncompleteStatements ) {
9601008 buildAllStatements ();
9611009 }
962- return mappedStatements .containsKey (statementName );
1010+ return mappedStatements .containsKey (this .getMappedStatementId (statementName ))
1011+ || this .getSupportDynamicRoutingDataSource () && mappedStatements .containsKey (statementName );
9631012 }
9641013
9651014 public void addCacheRef (String namespace , String referencedNamespace ) {
@@ -1113,7 +1162,6 @@ protected static class StrictMap<V> extends ConcurrentHashMap<String, V> {
11131162 private static final long serialVersionUID = -4950446264854982944L ;
11141163 private final String name ;
11151164 private BiFunction <V , V , String > conflictMessageProducer ;
1116- private static final Object AMBIGUITY_INSTANCE = new Object ();
11171165
11181166 public StrictMap (String name , int initialCapacity , float loadFactor ) {
11191167 super (initialCapacity , loadFactor );
@@ -1163,7 +1211,7 @@ public V put(String key, V value) {
11631211 if (super .get (shortKey ) == null ) {
11641212 super .put (shortKey , value );
11651213 } else {
1166- super .put (shortKey , (V ) AMBIGUITY_INSTANCE );
1214+ super .put (shortKey , (V ) new Ambiguity ( shortKey ) );
11671215 }
11681216 }
11691217 return super .put (key , value );
@@ -1184,13 +1232,25 @@ public V get(Object key) {
11841232 if (value == null ) {
11851233 throw new IllegalArgumentException (name + " does not contain value for " + key );
11861234 }
1187- if (AMBIGUITY_INSTANCE == value ) {
1188- throw new IllegalArgumentException (key + " is ambiguous in " + name
1235+ if (value instanceof Ambiguity ) {
1236+ throw new IllegalArgumentException ((( Ambiguity ) value ). getSubject () + " is ambiguous in " + name
11891237 + " (try using the full name including the namespace, or rename one of the entries)" );
11901238 }
11911239 return value ;
11921240 }
11931241
1242+ protected static class Ambiguity {
1243+ private final String subject ;
1244+
1245+ public Ambiguity (String subject ) {
1246+ this .subject = subject ;
1247+ }
1248+
1249+ public String getSubject () {
1250+ return subject ;
1251+ }
1252+ }
1253+
11941254 private String getShortName (String key ) {
11951255 final String [] keyParts = key .split ("\\ ." );
11961256 return keyParts [keyParts .length - 1 ];
0 commit comments