Skip to content

Commit 5589317

Browse files
committed
initialize all of the statements which is marked datasourceId when configuration set supportDynamicRoutingDataSource. The databaseIdProvider provide current databaseid for statement match.
1 parent 1a145cd commit 5589317

File tree

2 files changed

+92
-22
lines changed

2 files changed

+92
-22
lines changed

src/main/java/org/apache/ibatis/builder/xml/XMLStatementBuilder.java

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2024 the original author or authors.
2+
* Copyright 2009-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -59,7 +59,8 @@ public void parseStatementNode() {
5959
String id = context.getStringAttribute("id");
6060
String databaseId = context.getStringAttribute("databaseId");
6161

62-
if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
62+
if (!this.configuration.getSupportDynamicRoutingDataSource()
63+
&& !databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
6364
return;
6465
}
6566

@@ -117,9 +118,18 @@ public void parseStatementNode() {
117118
String resultSets = context.getStringAttribute("resultSets");
118119
boolean dirtySelect = context.getBooleanAttribute("affectData", Boolean.FALSE);
119120

120-
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap,
121-
parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered,
122-
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets, dirtySelect);
121+
if (databaseId != null && databaseId.contains(";")) {
122+
String[] databaseIds = databaseId.split(";");
123+
for (String dbId : databaseIds) {
124+
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
125+
parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache,
126+
resultOrdered, keyGenerator, keyProperty, keyColumn, dbId, langDriver, resultSets, dirtySelect);
127+
}
128+
} else {
129+
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
130+
parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache,
131+
resultOrdered, keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets, dirtySelect);
132+
}
123133
}
124134

125135
private void processSelectKeyNodes(String id, Class<?> parameterTypeClass, LanguageDriver langDriver) {

src/main/java/org/apache/ibatis/session/Configuration.java

+77-17
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.apache.ibatis.session;
1717

18+
import java.sql.SQLException;
1819
import java.util.Arrays;
1920
import java.util.Collection;
2021
import java.util.HashMap;
@@ -23,6 +24,7 @@
2324
import java.util.LinkedList;
2425
import java.util.List;
2526
import java.util.Map;
27+
import java.util.Objects;
2628
import java.util.Properties;
2729
import java.util.Set;
2830
import java.util.concurrent.ConcurrentHashMap;
@@ -69,6 +71,7 @@
6971
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
7072
import org.apache.ibatis.logging.stdout.StdOutImpl;
7173
import org.apache.ibatis.mapping.BoundSql;
74+
import org.apache.ibatis.mapping.DatabaseIdProvider;
7275
import org.apache.ibatis.mapping.Environment;
7376
import org.apache.ibatis.mapping.MappedStatement;
7477
import 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

Comments
 (0)