Vorwort
Spring konfiguriert mehrere Datenquellen dynamisch, dh die Aufteilung von Daten in große Anwendungen und die Verwendung mehrerer Datenbankinstanzen für die Verwaltung, wodurch die horizontale Skalierbarkeit des Systems effektiv verbessert werden kann. Eine solche Lösung unterscheidet sich von der herkömmlichen Einzeldateninstanzlösung, bei der das Programm während der Laufzeit basierend auf der aktuellen Anforderung und dem Systemstatus dynamisch entscheiden muss, in welcher Datenbankinstanz die Daten gespeichert und aus welcher Datenbank die Daten extrahiert werden sollen.
Spring 2.x und spätere Versionen verwenden den Proxy-Modus. Dies bedeutet, dass wir eine virtuelle Datenquelle in der Lösung implementieren und diese zum Kapseln der Datenquellenauswahllogik verwenden, sodass die Datenquellenauswahllogik effektiv sein kann übertragen von getrennt vom Kunden. Der Client stellt den für die Auswahl erforderlichen Kontext bereit (da dieser vom Client bekannt ist) und die virtuelle DataSource implementiert die Auswahl der Datenquelle basierend auf dem vom Client bereitgestellten Kontext.
Implementierung
Die spezifische Implementierung besteht darin, dass die virtuelle DataSource nur AbstractRoutingDataSource erben muss, um discoverCurrentLookupKey() zu implementieren, in dem die Auswahllogik der Datenquelle gekapselt ist.
1. Konfigurieren Sie mehrere Datenquellen dynamisch
1. Datenquellennamen-Konstantenklasse:
/** * 动态配置多数据源 * 数据源的名称常量类 * @author LONGHUI_LUO * */ public class DataSourceConst { public static final String TEST="test"; public static final String USER="User"; }
2. Erstellen Sie eine Klasse zum Abrufen und Festlegen der Kontextumgebung, die hauptsächlich für die Änderung des Namens der Kontextdatenquelle verantwortlich ist:
/** * 获得和设置上下文环境 主要负责改变上下文数据源的名称 * * @author LONGHUI_LUO * */ public class DataSourceContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); // 线程本地环境 // 设置数据源类型 public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } // 获取数据源类型 public static String getDataSourceType() { return (String) contextHolder.get(); } // 清除数据源类型 public static void clearDataSourceType() { contextHolder.remove(); } }
3. Beachten Sie, dass diese Klasse AbstractRoutingDataSource erben und die Methode „determineCurrentLookupKey“ implementieren muss. Diese Methode gibt ein Objekt zurück, normalerweise eine Zeichenfolge:
/** * 建立动态数据源 * * @author LONGHUI_LUO * */ public class DynamicDataSource extends AbstractRoutingDataSource { protected Object determineCurrentLookupKey() { // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型 return DataSourceContextHolder.getDataSourceType(); } }
<!-- 数据源相同的内容 --> <bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="username" value="sa" /> <property name="password" value="net2com" /> </bean> <!-- start以下配置各个数据源的特性 --> <bean parent="parentDataSource" id="testDataSource"> <propertynamepropertyname="url" value="jdbc:sqlserver://localhost:1433;databaseName=test" /> </bean> <bean parent="parentDataSource" id="UserDataSource"> <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=User" /> </bean> <!-- end 配置各个数据源的特性 -->
<bean class="com.xxxx.datasouce.DynamicDataSource" id="dataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="testDataSource" key="test"></entry> <entry value-ref="UserDataSource" key="User"></entry> </map> </property> <property name="defaultTargetDataSource" ref="testDataSource" ></property> </bean>