Spring動態配置多數據源,即在大型應用中對數據進行切分,而且採用多個數據庫實例進行管理,這樣能夠有效提升系統的水平伸縮性。而這樣的方案就會不一樣於常見的單一數據實例的方案,這就要程序在運行時根據當時的請求及系統狀態來動態的決定將數據存儲在哪一個數據庫實例中,以及從哪一個數據庫提取數據。java
Spring配置多數據源的方式和具體使用過程。
Spring對於多數據源,以數據庫表爲參照,大致上能夠分紅兩大類狀況:
一是,表級上的跨數據庫。即,對於不一樣的數據庫卻有相同的表(表名和表結構徹底相同)。
二是,非表級上的跨數據庫。即,多個數據源不存在相同的表。
Spring2.x的版本中採用Proxy模式,就是咱們在方案中實現一個虛擬的數據源,而且用它來封裝數據源選擇邏輯,這樣就能夠有效地將數據源選擇邏輯從Client中分離出來。Client提供選擇所需的上下文(由於這是Client所知道的),由虛擬的DataSource根據Client提供的上下文來實現數據源的選擇。
具體的實現就是,虛擬的DataSource僅需繼承AbstractRoutingDataSource實現determineCurrentLookupKey()在其中封裝數據源的選擇邏輯。 spring
步驟以下:sql
1、動態配置多數據源
1. 數據源的名稱常量類:數據庫
1 package com.login; 2 3 public class DataSourceConst { 4 5 public static final String Admin = "admin"; 6 public static final String User = "user"; 7 }
2. 創建一個得到和設置上下文環境的類,主要負責改變上下文數據源的名稱:app
package com.login; public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();//線程本地環境 //設置數據源類型 public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } //獲取數據源類型 public static String getDataSourceType() { return contextHolder.get(); } //清除數據源類型 public static void clearDataSourceType() { contextHolder.remove(); } }
3. 創建動態數據源類,注意,這個類必須繼承AbstractRoutingDataSource,且實現方法 determineCurrentLookupKey,該方法返回一個Object,通常是返回字符串:ide
1 package com.login; 2 3 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 4 5 public class DynamicDataSource extends AbstractRoutingDataSource { 6 7 @Override 8 protected Object determineCurrentLookupKey() { 9 // TODO Auto-generated method stub 10 return DataSourceContextHolder.getDataSourceType(); 11 } 12 13 }
4. 編寫spring的配置文件配置多個數據源測試
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 6 7 <!-- spring 讀取數據庫配置文件 --> 8 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 9 <property name="location" value="classpath:jdbc.properties" /> 10 </bean> 11 12 <bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 13 <property name="driverClass" value="${jdbc.driver}"></property> 14 <property name="user" value="${jdbc.username}"></property> 15 <property name="password" value="${jdbc.password}"></property> 16 <property name="autoCommitOnClose" value="true"/> 17 <property name="checkoutTimeout" value="${cpool.checkoutTimeout}"/> 18 <property name="initialPoolSize" value="${cpool.initialPoolSize}"/> 19 <property name="minPoolSize" value="${cpool.minPoolSize}"/> 20 <property name="maxPoolSize" value="${cpool.maxPoolSize}"/> 21 <property name="maxIdleTime" value="${cpool.maxIdleTime}"/> 22 <property name="preferredTestQuery" value="${cpool.preferredTestQuery}"/> 23 <property name="acquireIncrement" value="${cpool.acquireIncrement}"/> 24 <property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}"/> 25 </bean> 26 27 <bean id="adminDataSource" parent="parentDataSource"> 28 <property name="jdbcUrl" value="${jdbc.url}"></property> 29 </bean> 30 <bean id="userDataSource" parent="parentDataSource"> 31 <property name="jdbcUrl" value="${jdbc.url1}"></property> 32 </bean> 33 34 <bean id="dataSource" class="com.login.DynamicDataSource"> 35 <property name="targetDataSources"> 36 <map key-type="java.lang.String"> 37 <entry value-ref="adminDataSource" key="admin"></entry> 38 <entry value-ref="userDataSource" key="user"></entry> 39 </map> 40 </property> 41 <property name="defaultTargetDataSource" ref="adminDataSource"></property> 42 </bean> 43 44 <!-- Spring提供的iBatis的SqlMap配置 --> 45 <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> 46 <property name="configLocation" value="classpath:sqlMapConfig.xml" /> 47 <property name="dataSource" ref="dataSource" /> 48 </bean> 49 50 51 </beans>
5.配置daoui
1 <bean name="loginDao" class="com.login.LoginDao"> 2 <property name="sqlMapClient" ref="sqlMapClient"></property> 3 </bean> 4 <bean name="loginService" class="com.login.LoginService"> 5 <property name="loginDao" ref="loginDao"></property> 6 </bean>
6.編寫測試類url
1 BeanFactory beanFactory = (BeanFactory)(new ClassPathXmlApplicationContext("applicationContext.xml")); 2 LoginDao loginDao = (LoginDao)beanFactory.getBean("loginDao"); 3 DataSourceContextHolder.setDataSourceType(DataSourceConst.Admin); 4 5 loginDao.getUserInfo(); 6 7 DataSourceContextHolder.setDataSourceType(DataSourceConst.User); 8 9 loginDao.getUserInfo();