前言
Spring動態配置多重資料來源,即在大型應用中對資料進行切分,並且採用多個資料庫執行個體進行管理,這樣可以有效提高系統的水平伸縮性。而這樣的方案就會不同於常見的單一資料實例的方案,這就要程式在運行時根據當時的請求及系統狀態來動態的決定將資料儲存在哪個資料庫實例中,以及從哪個資料庫提取資料。
Spring2.x以後的版本中採用Proxy模式,就是我們在方案中實作一個虛擬的資料來源,並且用它來封裝資料來源選擇邏輯,這樣就可以有效地將資料來源選擇邏輯從Client中分離出來。 Client提供選擇所需的上下文(因為這是Client所知道的),由虛擬的DataSource根據Client提供的上下文來實現資料來源的選擇。
實作
具體的實作就是,虛擬的DataSource只需繼承AbstractRoutingDataSource實作determineCurrentLookupKey()在其中封裝資料來源的選擇邏輯。
一、動態配置多重資料來源
1. 資料來源的名稱常數類別:
/** * 动态配置多数据源 * 数据源的名称常量类 * @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>目標資料來源,