在實(shí)際項(xiàng)目中時(shí)常需要連接多個(gè)數(shù)據(jù)庫(kù),而且不同的業(yè)務(wù)需求在實(shí)現(xiàn)過程當(dāng)中往往需要訪問不同的數(shù)據(jù)庫(kù)。
jdbc.properties配置文件,配置多個(gè)dataSource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
##########################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配置文件中去,同時(shí)配置DynamicDataSource的targetDataSources(多數(shù)據(jù)源目標(biāo))屬性的Map映射,使用動(dòng)態(tài)數(shù)據(jù)源DynamicDataSource是繼承與AbstractRoutingDataSource,而AbstractRoutingDataSource又是繼承于org.springframework.jdbc.datasource.AbstractDataSource,AbstractDataSource實(shí)現(xiàn)了統(tǒng)一的DataSource接口,所以DynamicDataSource同樣可以當(dāng)一個(gè)DataSource使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<!-- 數(shù)據(jù)庫(kù)連接池配置 --> <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" /> <!-- 配置獲取連接等待超時(shí)的時(shí)間 --> <property name= "maxWait" value= "30000" /> <!-- 配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒 --> <property name= "timeBetweenEvictionRunsMillis" value= "60000" /> <!-- 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 --> <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> <!-- 動(dòng)態(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動(dòng)態(tài)數(shù)據(jù)源類,擴(kuò)展Spring的AbstractRoutingDataSource抽象類,實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源,AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是實(shí)現(xiàn)數(shù)據(jù)源的route的核心.這里對(duì)該方法進(jìn)行Override:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.yahu.core.dao; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /******************************************************************* * @describe : 建立動(dòng)態(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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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(); } } |
動(dòng)態(tài)數(shù)據(jù)源的管理,如何選擇控制每個(gè)業(yè)務(wù)中需要的具體數(shù)據(jù)源,可以使用手動(dòng)控制,業(yè)務(wù)層通過加入以下代碼
1
|
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATASOURCE); |
即可實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源,如果在service層有比較統(tǒng)一的規(guī)則的話,也可以使用aop設(shè)置數(shù)據(jù)源使用,這里一般都是一個(gè)service一個(gè)數(shù)據(jù)源,所以最好使用aop在service層執(zhí)行完之后統(tǒng)一調(diào)用
1
|
CustomerContextHolder.clearCustomerType(); |
清空數(shù)據(jù)源信息。
當(dāng)然,在上面配置里面有個(gè)參數(shù)defaultTargetDataSource為默認(rèn)數(shù)據(jù)源,就是不設(shè)置數(shù)據(jù)源的話,就是用這個(gè)數(shù)據(jù)源。
以上這篇Spring整合多數(shù)據(jù)源實(shí)現(xiàn)動(dòng)態(tài)切換的實(shí)例講解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。