一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作

Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作

2020-09-19 00:28小小工匠 JAVA教程

這篇文章主要介紹了Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

實(shí)現(xiàn)思路

重寫Spring的AbstractRoutingDataSource抽象類的determineCurrentLookupKey方法。

我們來(lái)看下Spring-AbstractRoutingDataSource的源碼

Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作

AbstractRoutingDataSource獲取數(shù)據(jù)源之前會(huì)先調(diào)用determineCurrentLookupKey方法查找當(dāng)前的lookupKey。

?
1
2
3
4
Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = this.resolvedDataSources.get(lookupKey);
.......
return dataSource;

lookupKey為數(shù)據(jù)源標(biāo)識(shí),因此通過(guò)重寫這個(gè)查找數(shù)據(jù)源標(biāo)識(shí)的方法就可以讓spring切換到指定的數(shù)據(jù)源.

從變量定義中可以知道resolvedDataSources為Map類型的對(duì)象。

private Map<Object, DataSource> resolvedDataSources;

示例

Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作

步驟一 新建Maven工程

依賴如下: pom.xml

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.artisan</groupId>
    <artifactId>dynamicDataSource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>dynamicDataSource</name>
    <url>http://maven.apache.org</url>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <file.encoding>UTF-8</file.encoding>
        <spring.version>4.3.9.RELEASE</spring.version>
        <servlet.version>3.1.0</servlet.version>
        <aspectj.version>1.8.1</aspectj.version>
        <commons-dbcp.version>1.4</commons-dbcp.version>
        <jetty.version>8.1.8.v20121106</jetty.version>
        <log4j.version>1.2.17</log4j.version>
        <log4j2.version>2.8.2</log4j2.version>
        <testng.version>6.8.7</testng.version>
        <oracle.version>11.2.0.4.0</oracle.version>
        <jstl.version>1.2</jstl.version>
    </properties>
 
    <dependencies>
        <!-- spring 依賴 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
 
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>${commons-dbcp.version}</version>
        </dependency>
 
 
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
 
 
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
 
        <!-- oracle jdbc driver -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>${oracle.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
        <!--
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        
    </dependencies>
 
    <build>
        <!-- 使用JDK1.7編譯 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

步驟二 繼承AbstractRoutingDataSource并重寫determineCurrentLookupKey方法獲取特定數(shù)據(jù)源

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.artisan.dynamicDB;
 
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
/**
 *
 *
 * @ClassName: DynamicDataSource
 *
 * @Description:
 *  AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是實(shí)現(xiàn)數(shù)據(jù)源的route的核心
 *  .需要重寫該方法
 *
 * @author: Mr.Yang
 *
 * @date: 2017年7月24日 下午8:28:46
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
 
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceHolder.getDataSource();
    }
}

步驟三 創(chuàng)建DynamicDataSourceHolder用于持有當(dāng)前線程中使用的數(shù)據(jù)源標(biāo)識(shí)

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.artisan.dynamicDB;
 
/**
 *
 *
 * @ClassName: DynamicDataSourceHolder
 *
 * @Description:創(chuàng)建DynamicDataSourceHolder用于持有當(dāng)前線程中使用的數(shù)據(jù)源標(biāo)識(shí)
 *
 * @author: Mr.Yang
 *
 * @date: 2017年7月24日 下午8:23:50
 */
public class DynamicDataSourceHolder {
 
 /**
 * 數(shù)據(jù)源標(biāo)識(shí)保存在線程變量中,避免多線程操作數(shù)據(jù)源時(shí)互相干擾
 */
 private static final ThreadLocal<String> dataSourceHolder = new ThreadLocal<String>();
 
 /**
 *
 *
 * @Title: setDataSource
 *
 * @Description: 設(shè)置數(shù)據(jù)源
 *
 * @param dataSource
 *
 * @return: void
 */
 public static void setDataSource(String dataSource) {
 dataSourceHolder.set(dataSource);
 }
 
 /**
 *
 *
 * @Title: getDataSource
 *
 * @Description: 獲取數(shù)據(jù)源
 *
 * @return
 *
 * @return: String
 */
 public static String getDataSource() {
 return dataSourceHolder.get();
 }
 
 /**
 *
 *
 * @Title: clearDataSource
 *
 * @Description: 清除數(shù)據(jù)源
 *
 *
 * @return: void
 */
 public static void clearDataSource() {
 dataSourceHolder.remove();
 }
}

步驟四 配置多個(gè)數(shù)據(jù)源和DynamicDataSource的bean

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd
 http://www.springframework.org/schema/util
 http://www.springframework.org/schema/util/spring-util.xsd">
 
 <!-- 基類包,將標(biāo)注Spring注解的類自動(dòng)轉(zhuǎn)化Bean,同時(shí)完成Bean的注入 -->
 <context:component-scan base-package="com.artisan"/>
 
 <!-- 使用context命名空間,在xml文件中配置數(shù)據(jù)庫(kù)的properties文件 -->
 <context:property-placeholder location="classpath:jdbc.properties" />
 
 <!-- 配置數(shù)據(jù)源-->
 
 <!-- 主站點(diǎn)的數(shù)據(jù)源 -->
 <bean id="dataSourcePR" class="org.apache.commons.dbcp.BasicDataSource"
 destroy-method="close"
 p:driverClassName="${jdbc.driverClassNamePR}"
 p:url="${jdbc.urlPR}"
 p:username="${jdbc.usernamePR}"
 p:password="${jdbc.passwordPR}" />
 
 <!-- 備用站點(diǎn)的數(shù)據(jù)源 -->
 <bean id="dataSourceDR" class="org.apache.commons.dbcp.BasicDataSource"
 destroy-method="close"
 p:driverClassName="${jdbc.driverClassNameDR}"
 p:url="${jdbc.urlDR}"
 p:username="${jdbc.usernameDR}"
 p:password="${jdbc.passwordDR}" />
 
 <!-- 主站點(diǎn)cc實(shí)例數(shù)據(jù)源 -->
 <bean id="dataSourceCC" class="org.apache.commons.dbcp.BasicDataSource"
 destroy-method="close"
 p:driverClassName="${jdbc.driverClassNameCC}"
 p:url="${jdbc.urlCC}"
 p:username="${jdbc.usernameCC}"
 p:password="${jdbc.passwordCC}" />
 
 
 <bean id="dynamicDataSource" class="com.artisan.dynamicDB.DynamicDataSource">
 <property name="targetDataSources" ref="dynamicDatasourceMap" />
 <!-- 默認(rèn)數(shù)據(jù)源 -->
 <property name="defaultTargetDataSource" ref="dataSourcePR" />
 </bean>
 
 <!-- 指定lookupKey和與之對(duì)應(yīng)的數(shù)據(jù)源 -->
 <util:map id="dynamicDatasourceMap" key-type="java.lang.String">
 <entry key="dataSourcePR" value-ref="dataSourcePR" />
 <entry key="dataSourceDR" value-ref="dataSourceDR" />
 <entry key="dataSourceCC" value-ref="dataSourceCC" />
 </util:map>
 
 
 <!-- 配置Jdbc模板 JdbcTemplate使用動(dòng)態(tài)數(shù)據(jù)源的配置 -->
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
 p:dataSource-ref="dynamicDataSource" />
 
 <!-- 配置數(shù)據(jù)源注解的攔截規(guī)則,比如攔截service層或者dao層的所有方法,這里攔截了com.artisan下的全部方法 -->
 <bean id="dataSourceAspect" class="com.artisan.dynamicDB.DataSourceAspect" />
 <aop:config>
  <aop:aspect ref="dataSourceAspect">
  <!-- 攔截所有XXX方法 -->
  <aop:pointcut id="dataSourcePointcut" expression="execution(* com.artisan..*(..))"/>
  <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
  </aop:aspect>
 </aop:config>
 
 <!-- 配置事務(wù)管理器 -->
 <bean id="transactionManager"
 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
 p:dataSource-ref="dynamicDataSource" />
 
 <!-- 通過(guò)AOP配置提供事務(wù)增強(qiáng),讓com.artisan包下所有Bean的所有方法擁有事務(wù) -->
 <aop:config proxy-target-class="true">
 <aop:pointcut id="serviceMethod"
 expression="(execution(* com.artisan..*(..))) and (@annotation(org.springframework.transaction.annotation.Transactional))" />
 <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
 </aop:config>
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
 <tx:method name="*" />
 </tx:attributes>
 </tx:advice>
</beans>

配置到這里,我們就可以使用多個(gè)數(shù)據(jù)源了,只需要在操作數(shù)據(jù)庫(kù)之前只要DynamicDataSourceHolder.setDataSource(“dataSourcePR”)即可切換到數(shù)據(jù)源dataSourcePR并對(duì)數(shù)據(jù)庫(kù)dataSourcePR進(jìn)行操作了。

問(wèn)題:每次使用都需要調(diào)用DynamicDataSourceHolder#setDataSource,十分繁瑣,并且難以維護(hù)。

我們可以通過(guò)Spring的AOP和注解, 直接通過(guò)注解的方式指定需要訪問(wèn)的數(shù)據(jù)源。 繼續(xù)改進(jìn)下吧

步驟五 定義名為@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
package com.artisan.dynamicDB;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 *
 *
 * @ClassName: DataSource
 *
 *
 * @Description: 注解@DataSource既可以加在方法上,也可以加在接口或者接口的實(shí)現(xiàn)類上,優(yōu)先級(jí)別:方法>實(shí)現(xiàn)類>接口。
 *  如果接口、接口實(shí)現(xiàn)類以及方法上分別加了@DataSource注解來(lái)指定數(shù)據(jù)源,則優(yōu)先以方法上指定的為準(zhǔn)。
 *
 * @author: Mr.Yang
 *
 * @date: 2017年7月24日 下午9:59:29
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
 // 和配置文件中 dynamicDatasourceMap中的key保持一致
 public static String PR_RB = "dataSourcePR";
 
 public static String DR_RB = "dataSourceDR";
 
 public static String PR_CC = "dataSourceCC";
 
 /**
 *
 *
 * @Title: name
 *
 * @Description: 如果僅標(biāo)注@DataSource 默認(rèn)為PR_RB數(shù)據(jù)庫(kù)實(shí)例
 *
 * @return
 *
 * @return: String
 */
 String name() default DataSource.PR_RB;
 
}

步驟六 定義AOP切面以便攔截所有帶有注解@DataSource的方法,取出注解的值作為數(shù)據(jù)源標(biāo)識(shí)放到DynamicDataSourceHolder的線程變量中

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.artisan.dynamicDB;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
 
/**
 *
 *
 * @ClassName: DataSourceAspect
 *
 * @Description:
 *  定義AOP切面以便攔截所有帶有注解@DataSource的方法,取出注解的值作為數(shù)據(jù)源標(biāo)識(shí)放到DBContextHolder的線程變量中
 *
 * @author: Mr.Yang
 *
 * @date: 2017年7月25日 上午10:51:41
 */
public class DataSourceAspect {
 
 /**
 *
 *
 * @Title: intercept
 *
 * @Description: 攔截目標(biāo)方法,獲取由@DataSource指定的數(shù)據(jù)源標(biāo)識(shí),設(shè)置到線程存儲(chǔ)中以便切換數(shù)據(jù)源
 *
 * @param point
 * @throws Exception
 *
 * @return: void
 */
 public void intercept(JoinPoint point) throws Exception {
 Class<?> target = point.getTarget().getClass();
 MethodSignature signature = (MethodSignature) point.getSignature();
 // 默認(rèn)使用目標(biāo)類型的注解,如果沒(méi)有則使用其實(shí)現(xiàn)接口的注解
 for (Class<?> clazz : target.getInterfaces()) {
 resolveDataSource(clazz, signature.getMethod());
 }
 resolveDataSource(target, signature.getMethod());
 }
 
 /**
 *
 *
 * @Title: resolveDataSource
 *
 * @Description: 提取目標(biāo)對(duì)象方法注解和類型注解中的數(shù)據(jù)源標(biāo)識(shí)
 *
 * @param clazz
 * @param method
 *
 * @return: void
 */
 private void resolveDataSource(Class<?> clazz, Method method) {
 try {
 Class<?>[] types = method.getParameterTypes();
 // 默認(rèn)使用類型注解
 if (clazz.isAnnotationPresent(DataSource.class)) {
 DataSource source = clazz.getAnnotation(DataSource.class);
 DynamicDataSourceHolder.setDataSource(source.name());
 }
 // 方法注解可以覆蓋類型注解
 Method m = clazz.getMethod(method.getName(), types);
 if (m != null && m.isAnnotationPresent(DataSource.class)) {
 DataSource source = m.getAnnotation(DataSource.class);
 DynamicDataSourceHolder.setDataSource(source.name());
 }
 } catch (Exception e) {
 System.out.println(clazz + ":" + e.getMessage());
 }
 }
}

步驟七 在spring配置文件中配置攔截規(guī)則

?
1
2
3
4
5
6
7
8
9
<!-- 配置數(shù)據(jù)源注解的攔截規(guī)則,比如攔截service層或者dao層的所有方法,這里攔截了com.artisan下的全部方法 -->
<bean id="dataSourceAspect" class="com.artisan.dynamicDB.DataSourceAspect" />
<aop:config>
 <aop:aspect ref="dataSourceAspect">
 <!-- 攔截所有XXX方法 -->
 <aop:pointcut id="dataSourcePointcut" expression="execution(* com.artisan..*(..))"/>
 <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
 </aop:aspect>
</aop:config>

步驟八 使用注解切換多數(shù)據(jù)源

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
ExtractDataService.java
package com.artisan.extractService;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Service;
 
import com.artisan.dynamicDB.DataSource;
 
/**
 *
 *
 * @ClassName: ExtractDataService
 *
 * @Description: 業(yè)務(wù)類,這里暫時(shí)作為測(cè)試多數(shù)據(jù)源切換用
 *
 * @author: Mr.Yang
 *
 * @date: 2017年7月24日 下午9:07:38
 */
 
@Service
public class ExtractDataService {
 
 private static final Logger logger = LogManager
 .getLogger(ExtractDataService.class.getName());
 
 private JdbcTemplate jdbcTemplate;
 
 @Autowired
 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 this.jdbcTemplate = jdbcTemplate;
 }
 
 /**
 *
 *
 * @Title: selectDataFromPR
 *
 * @Description:
 *
 *
 * @return: void
 */
 @DataSource(name = DataSource.PR_RB)
 public void selectDataFromPR_RB() {
 String sql = "select subs_id from owe_event_charge where event_inst_id = 10229001 ";
 
 jdbcTemplate.query(sql, new RowCallbackHandler() {
 
 @Override
 public void processRow(ResultSet rs) throws SQLException {
 logger.info(rs.getInt("subs_id"));
 }
 });
 }
 
 @DataSource(name = DataSource.DR_RB)
 public void selectDataFromDR_RB() {
 // 改為通過(guò)注解指定DB
 // DynamicDataSourceHolder.setDataSource(DBContextHolder.DATA_SOURCE_DR);
 String sql = " select a.task_comments from nm_task_type a where a.task_name = 'ALARM_LOG_LEVEL' ";
 jdbcTemplate.query(sql, new RowCallbackHandler() {
 
 @Override
 public void processRow(ResultSet rs) throws SQLException {
 logger.info(rs.getString("task_comments"));
 }
 });
 }
 
 @DataSource(name = DataSource.PR_CC)
 public void selectDataFromPR_CC() {
 // DBContextHolder.setDataSource(DBContextHolder.DATA_SOURCE_CC);
 String sql = "select acc_nbr from acc_nbr where acc_nbr_id = 82233858 ";
 jdbcTemplate.query(sql, new RowCallbackHandler() {
 
 @Override
 public void processRow(ResultSet rs) throws SQLException {
 logger.info(rs.getString("acc_nbr"));
 }
 });
 
 }
}

步驟九 測(cè)試

?
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
50
51
52
53
package com.artisan;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 
import com.artisan.extractService.ExtractDataService;
 
/**
 *
 *
 * @ClassName: App
 *
 * @Description: 入口類
 *
 * @author: Mr.Yang
 *
 * @date: 2017年7月24日 下午8:50:25
 */
public class App {
 public static void main(String[] args) {
 try {
 // 加載日志框架 log4j2
 LoggerContext context = (LoggerContext) LogManager
 .getContext(false);
 ResourceLoader loader = new PathMatchingResourcePatternResolver();
 Resource resource = loader.getResource("classpath:log4j2.xml");
 
 context.setConfigLocation(resource.getFile().toURI());
 
 // 加載spring配置信息
 ApplicationContext ctx = new ClassPathXmlApplicationContext(
 "classpath:spring-context.xml");
 // 從容器中獲取Bean
 ExtractDataService service = ctx.getBean("extractDataService",
 ExtractDataService.class);
 // 從PR的RB實(shí)例中獲取數(shù)據(jù)
 service.selectDataFromPR_RB();
 // 從DR的RB實(shí)例中獲取數(shù)據(jù)
 service.selectDataFromDR_RB();
 // 從PR的CC實(shí)例中獲取數(shù)據(jù)
 service.selectDataFromPR_CC();
 
 } catch (IOException e) {
 e.printStackTrace();
 }
 
 }
}

其他代碼

log4j2.xml

?
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
<?xml version="1.0" encoding="UTF-8"?>
<!-- log4j2使用說(shuō)明:
使用方式如下:
private static final Logger logger = LogManager.getLogger(實(shí)際類名.class.getName());
-->
 
<!--日志級(jí)別以及優(yōu)先級(jí)排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,這個(gè)用于設(shè)置log4j2自身內(nèi)部的信息輸出,可以不設(shè)置,當(dāng)設(shè)置成trace時(shí),你會(huì)看到log4j2內(nèi)部各種詳細(xì)輸出-->
<!--monitorInterval:Log4j能夠自動(dòng)檢測(cè)修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)-->
<configuration status="info" monitorInterval="180">
 
 <!-- 文件路徑和文件名稱,方便后面引用 -->
 <Properties>
 <Property name="backupFilePatch">D:/workspace/workspace-sts/backupOracle/log/</Property>
 <Property name="fileName">backupOracle.log</Property>
 </Properties>
 <!--先定義所有的appender-->
 <appenders>
 <!--這個(gè)輸出控制臺(tái)的配置-->
 <Console name="Console" target="SYSTEM_OUT">
  <!--控制臺(tái)只輸出level及以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)-->
  <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />
  <!-- 輸出日志的格式-->
  <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
 </Console>
 
 <!--這個(gè)會(huì)打印出所有的信息,每次大小超過(guò)size,則這size大小的日志會(huì)自動(dòng)存入按年份-月份建立的文件夾下面并進(jìn)行壓縮,作為存檔-->
 <RollingFile name="RollingFile" fileName="${backupFilePatch}${fileName}"
  filePattern="${backupFilePatch}$${date:yyyy-MM}/app-%d{yyyyMMddHHmmssSSS}.log.gz">
  <PatternLayout
  pattern="%d{yyyy.MM.dd 'at' HH:mm:ss.SSS z} %-5level %class{36} %L %M - %msg%xEx%n" />
  <!-- 日志文件大小 -->
  <SizeBasedTriggeringPolicy size="20MB" />
  <!-- 最多保留文件數(shù) DefaultRolloverStrategy屬性如不設(shè)置,則默認(rèn)為最多同一文件夾下7個(gè)文件,這里設(shè)置了20 -->
  <DefaultRolloverStrategy max="20"/>
 </RollingFile>
 </appenders>
 
 <!--然后定義logger,只有定義了logger并引入的appender,appender才會(huì)生效-->
 <loggers>
 <!--過(guò)濾掉spring和mybatis的一些無(wú)用的DEBUG信息-->
 <logger name="org.springframework" level="INFO"></logger>
 <logger name="org.mybatis" level="INFO"></logger>
 <root level="trace">
  <appender-ref ref="RollingFile"/>
  <appender-ref ref="Console"/>
  </root>
 </loggers>
</configuration>

jdbc.properties

?
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
##########################
##
##
## dbcp datasource pool ,basic configuration first.
## the other parameters keep default for now , you can change them if you want
##
##
##########################
 
#Database in Lapaz
jdbc.driverClassNamePR=oracle.jdbc.driver.OracleDriver
jdbc.urlPR=jdbc:oracle:thin:@172.25.243.4:1521:xx
jdbc.usernamePR=xxx
jdbc.passwordPR=xxxxxxxx
 
#Database in Scluz
jdbc.driverClassNameDR=oracle.jdbc.driver.OracleDriver
jdbc.urlDR=jdbc:oracle:thin:@172.25.246.1:1521:xx
jdbc.usernameDR=xxx
jdbc.passwordDR=xxxxxxx
 
#Database in Lapaz
jdbc.driverClassNameCC=oracle.jdbc.driver.OracleDriver
jdbc.urlCC=jdbc:oracle:thin:@172.25.243.3:1521:xx
jdbc.usernameCC=xxx
jdbc.passwordCC=xxxxxx

運(yùn)行結(jié)果:

Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作

代碼

https://github.com/yangshangwei/DynamicDataSource

以上這篇Spring-基于Spring使用自定義注解及Aspect實(shí)現(xiàn)數(shù)據(jù)庫(kù)切換操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/yangshangwei/article/details/76223423

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久电影精品久久99久久 | 国模娜娜a4u1546全套 | 亚洲男人天堂影院 | 久久精品动漫99精品动漫 | 日本激情小说 | 国产精品一区二区三 | 免费观看欧美成人h | 国产在线视频资源 | 亚洲精品m在线观看 | 日韩欧美亚洲一区二区综合 | 亚洲AV无码A片在线观看蜜桃 | 2018高清国产一道国产 | 天堂资源在线www中文 | 女人和拘做受全过程免费 | 久久re这里精品在线视频7 | 无限在线看免费视频大全 | 精品国产麻豆免费人成网站 | 人人人人看人人人做人人 | 国产成+人+综合+亚洲欧美丁香花 | 日本视频免费在线观看 | 免费在线观看视频 | 97精品国产自在现线免费观看 | 97福利社 | 丰满大乳欲妇三级k8 | 国产麻豆网 | 日韩黄色录像 | 高清毛片一区二区三区 | chinese男同志gay免费 | 91热爆| 91传媒制片厂制作传媒破解版 | 欧美日韩亚洲高清不卡一区二区三区 | 日本高h| 精品欧美一区二区三区四区 | 亚洲 欧美 中文 日韩 视频 | 青春学堂在线观看 | 国产欧美日韩综合二区三区 | 亚洲国产欧美在线人网站 | 2020年国产精品午夜福利在线观看 | 日本不卡免费新一二三区 | 国产成人h视频在线播放网站 | 四虎在线精品免费高清在线 |