Spring動態配置多數據源,即在大型應用中對數據進行切分,並且采用多個數據庫實例進行管理,這樣可以有效提高系統的水平伸縮性。而這樣的方案就會不同於常見的單一數據實例的方案,這就要程序在運行時根據當時的請求及系統狀態來動態的決定將數據存儲在哪個數據庫實例中,以及從哪個數據庫提取數據。
Spring2.x以后的版本中采用Proxy模式,就是我們在方案中實現一個虛擬的數據源,並且用它來封裝數據源選擇邏輯,這樣就可以有效地將數據源選擇邏輯從Client中分離出來。Client提供選擇所需的上下文(因為這是Client所知道的),由虛擬的DataSource根據Client提供的上下文來實現數據源的選擇。
實現
- /**
- * 動態配置多數據源
- * 數據源的名稱常量類
- * @author LONGHUI_LUO
- *
- */
- public class DataSourceConst {
- public static final String TEST="test";
- public static final String USER="User";
- }
2. 建立一個獲得和設置上下文環境的類,主要負責改變上下文數據源的名稱:
- /**
- * 獲得和設置上下文環境 主要負責改變上下文數據源的名稱
- *
- * @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. 建立動態數據源類,注意,這個類必須繼承AbstractRoutingDataSource,且實現方法determineCurrentLookupKey,該方法返回一個Object,一般是返回字符串:
- /**
- * 建立動態數據源
- *
- * @author LONGHUI_LUO
- *
- */
- public class DynamicDataSource extends AbstractRoutingDataSource {
- protected Object determineCurrentLookupKey() {
- // 在進行DAO操作前,通過上下文環境變量,獲得數據源的類型
- return DataSourceContextHolder.getDataSourceType();
- }
- }
4. 編寫spring的配置文件配置多個數據源
- <!-- 數據源相同的內容 -->
- <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 配置各個數據源的特性 -->
5. 編寫spring配置文件配置多數據源映射關系
- <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>
在這個配置中第一個property屬性配置目標數據源,<map key-type="java.lang.String">中的key-type必須要和靜態鍵值對照類DataSourceConst中的值的類型相 同;<entry key="User" value-ref="userDataSource"/>中key的值必須要和靜態鍵值對照類中的值相同,如果有多個值,可以配置多個< entry>標簽。第二個property屬性配置默認的數據源。
動態切換是數據源
- DataSourceContextHolder.setDataSourceType(DataSourceConst.TEST);