Spring整合多數(shù)據(jù)源實現(xiàn)動態(tài)切換的實例講解
在實際項目中時常需要連接多個數(shù)據(jù)庫,而且不同的業(yè)務(wù)需求在實現(xiàn)過程當中往往需要訪問不同的數(shù)據(jù)庫。
jdbc.properties配置文件,配置多個dataSource
##########################MySQL##################################### hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect connection.driver_class=com.mysql.jdbc.Driver connection.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8 connection.username=yahu connection.password=123456 ##########################Oracle##################################### connection1.driver_class=oracle.jdbc.driver.OracleDriver connection1.url=jdbc\:oracle\:thin\:@localhost\:1521/MEDB connection1.username=yahu connection1.password=123456 ##########################Sql Server2008##################################### connection2.driver_class=net.sourceforge.jtds.jdbc.Driver connection2.url=jdbc:jtds:sqlserver://localhost:1433;DatabaseName=test connection2.username=yahu connection2.password=123456
spring-config.xml配置文件如下,將DynamicDataSource Bean加入到Spring的上下文xml配置文件中去,同時配置DynamicDataSource的targetDataSources(多數(shù)據(jù)源目標)屬性的Map映射,使用動態(tài)數(shù)據(jù)源DynamicDataSource是繼承與AbstractRoutingDataSource,而AbstractRoutingDataSource又是繼承于org.springframework.jdbc.datasource.AbstractDataSource,AbstractDataSource實現(xiàn)了統(tǒng)一的DataSource接口,所以DynamicDataSource同樣可以當一個DataSource使用:
<!-- 數(shù)據(jù)庫連接池配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${connection.driver_class}" />
<property name="url" value="${connection.url}" />
<property name="username" value="${connection.username}" />
<property name="password" value="${connection.password}" />
<property name="initialSize" value="5" />
<property name="minIdle" value="1" />
<property name="maxActive" value="200" />
<!-- 配置獲取連接等待超時的時間 -->
<property name="maxWait" value="30000" />
<!-- 配置間隔多久才進行一次檢測,檢測需要關(guān)閉的空閑連接,單位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
</bean>
<!-- Oracle -->
<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${connection1.driver_class}" />
<property name="url" value="${connection1.url}" />
<property name="username" value="${connection1.username}" />
<property name="password" value="${connection1.password}" />
</bean>
<!-- Sql server 2008 -->
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${connection2.driver_class}" />
<property name="url" value="${connection2.url}" />
<property name="username" value="${connection2.username}" />
<property name="password" value="${connection2.password}" />
</bean>
<!-- 動態(tài)數(shù)據(jù)源 -->
<bean id="dynamicDataSource" class="com.yahu.core.dao.DynamicDataSource">
<!-- 通過key-value的形式來關(guān)聯(lián)數(shù)據(jù)源 -->
<property name="targetDataSources">
<map>
<entry value-ref="dataSource" key="datasource" />
<entry value-ref="dataSource1" key="datasource1" />
<entry value-ref="dataSource2" key="datasource2" />
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource" />
</bean>
DynamicDataSource動態(tài)數(shù)據(jù)源類,擴展Spring的AbstractRoutingDataSource抽象類,實現(xiàn)動態(tài)數(shù)據(jù)源,AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是實現(xiàn)數(shù)據(jù)源的route的核心.這里對該方法進行Override:
package com.yahu.core.dao;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/*******************************************************************
* @describe : 建立動態(tài)數(shù)據(jù)源類 必須繼承AbstractRoutingDataSource
********************************************************************/
public class DynamicDataSource extends AbstractRoutingDataSource {
//coverity 修改
//private Log log = LogFactory.getLog(getClass());
protected Object determineCurrentLookupKey() {
String value = CustomerContextHolder.getCustomerType();
//log.info(value);
return value;
}
}
獲得和設(shè)置上下文環(huán)境,為一線程安全的ThreadLocal:
package com.yahu.core.dao;
/*******************************************************************
* @describe : 獲得和設(shè)置上下文環(huán)境
********************************************************************/
public class CustomerContextHolder {
/**
* mysql
*/
public static final String DATASOURCE = "datasource";
/**
* oracle
*/
public static final String DATASOURCE_1 = "datasource1";
/**
* sql server
*/
public static final String DATASOURCE_2 = "datasource2";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
動態(tài)數(shù)據(jù)源的管理,如何選擇控制每個業(yè)務(wù)中需要的具體數(shù)據(jù)源,可以使用手動控制,業(yè)務(wù)層通過加入以下代碼
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATASOURCE);
即可實現(xiàn)動態(tài)切換數(shù)據(jù)源,如果在service層有比較統(tǒng)一的規(guī)則的話,也可以使用aop設(shè)置數(shù)據(jù)源使用,這里一般都是一個service一個數(shù)據(jù)源,所以最好使用aop在service層執(zhí)行完之后統(tǒng)一調(diào)用
CustomerContextHolder.clearCustomerType();
清空數(shù)據(jù)源信息。
當然,在上面配置里面有個參數(shù)defaultTargetDataSource為默認數(shù)據(jù)源,就是不設(shè)置數(shù)據(jù)源的話,就是用這個數(shù)據(jù)源。
以上這篇Spring整合多數(shù)據(jù)源實現(xiàn)動態(tài)切換的實例講解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Spring Boot 動態(tài)數(shù)據(jù)源示例(多數(shù)據(jù)源自動切換)
- Springboot如何設(shè)置多數(shù)據(jù)源,隨時切換
- SpringBoot AOP方式實現(xiàn)多數(shù)據(jù)源切換的方法
- Spring實現(xiàn)動態(tài)切換多數(shù)據(jù)源的解決方案
- spring boot+mybatis 多數(shù)據(jù)源切換(實例講解)
- Spring配置多數(shù)據(jù)源切換
- 詳解Spring多數(shù)據(jù)源如何切換
- Spring通過攔截器實現(xiàn)多數(shù)據(jù)源切換的示例代碼
相關(guān)文章
Java使用Thumbnailator實現(xiàn)快速處理圖片
它提供了簡單易用的API,可以輕松地生成縮略圖并進行各種操作,Thumbnailator是一個Java庫,用于創(chuàng)建和操作圖像縮略圖,下面我們就來看看具體的操作吧2025-04-04
解讀List?list=new?ArrayList()是怎么回事
這篇文章主要介紹了解讀List?list=new?ArrayList()是怎么回事,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
Java線程安全的計數(shù)器簡單實現(xiàn)代碼示例
這篇文章主要介紹了Java線程安全的計數(shù)器簡單實現(xiàn)代碼示例,具有一定參考價值,需要的朋友可以了解下。2017-10-10
spring 重復(fù)注解和aop攔截的實現(xiàn)示例
本文主要介紹了spring 重復(fù)注解和aop攔截的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
Java thread.isInterrupted() 返回值不確定結(jié)果分析解決
這篇文章主要介紹了Java thread.isInterrupted() 返回值不確定結(jié)果分析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12

