此文幾處有引用別人博客內(nèi)容,如有侵權(quán)表示歉意!
web項(xiàng)目中可能會(huì)遇到多數(shù)據(jù)源的情況,這個(gè)時(shí)候我們需要在不同的情況下使用不同的數(shù)據(jù)源對(duì)不同的數(shù)據(jù)庫進(jìn)行訪問,最典型的案例是數(shù)據(jù)的讀寫分離。
多數(shù)據(jù)源的設(shè)計(jì)思路:
多數(shù)據(jù)源的具體配置步驟:
配置文件中,配置不同的數(shù)據(jù)源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/>
bean>

<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url2}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/>
bean>
2.實(shí)現(xiàn)類 并繼承org..jdbc...ource類spring配置動(dòng)態(tài)數(shù)據(jù)源,重寫upKey()方法:
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {

return DatabaseContextHolder.getCustomerType();
}
}
實(shí)現(xiàn)r類spring配置動(dòng)態(tài)數(shù)據(jù)源,內(nèi)部實(shí)現(xiàn) 類來保證線程安全
public class DatabaseContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();
public static void setCustomerType(String customerType) {contextHolder.set(customerType);}
public static String getCustomerType() {return contextHolder.get();}
public static void clearCustomerType() {contextHolder.remove();}
}
4.配置數(shù)據(jù)源集合
<bean id="dynamicDataSource" class="com.laie.pa.common.dao.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource" key="dataSource">entry>
<entry value-ref="dataSource2" key="dataSource2">entry>
map>
property>
<!—配置默認(rèn)數(shù)據(jù)源 -->
<property name="defaultTargetDataSource" ref="dataSource">property>
bean>
配置數(shù)據(jù)源切換
5.1 實(shí)現(xiàn)r 類并配置Bean
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
@Component
public class DataSourceInterceptor {
public void setdataSourceOne(JoinPoint jp) {
DatabaseContextHolder.setCustomerType("dataSource");
}
public void setdataSourceTwo(JoinPoint jp) {
DatabaseContextHolder.setCustomerType("dataSource2");
}

}
.xml 文件配置此Bean
id="dataSourceInterceptor" class="com.laie.pa.common.dao.DataSourceInterceptor" />
5.2 配置AOP 實(shí)現(xiàn)數(shù)據(jù)源切換
<aop:config>
<aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor">
<aop:pointcut id="daoOne" expression="execution(* com.laie.pa.action.*.*(..))" />
<aop:pointcut id="daoTwo" expression="execution(* com.laie.pa.action2.*.*(..))" />
<aop:before pointcut-ref="daoOne" method="setdataSourceOne" />
<aop:before pointcut-ref="daoTwo" method="setdataSourceTwo" />
aop:aspect>
aop:config>
注:實(shí)現(xiàn)切換利用了aop中配置了執(zhí)行的包下的所有方法使用不同的數(shù)據(jù)源。