1. 程式人生 > >Spring配置多個數據源,並實現資料來源的動態切換

Spring配置多個數據源,並實現資料來源的動態切換

1.首先在config.properties檔案中配置兩個資料庫連線的基本資料。這個省略了
2.在spring配置檔案中配置這兩個資料來源:
資料來源1

 <!-- initialSize初始化時建立物理連線的個數0  maxActive最大連線池數量8 minIdle最小連線池數量0-->
    <bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" scope="singleton">
        <property name="username" value="${jdbc.username}"
/>
<property name="password" value="${jdbc.password}" /> <property name="url" value="${jdbc.url}" /> <property name="initialSize" value="${jdbc.init}" /> <property name="maxActive" value="${jdbc.max}" /> <property name="minIdle" value
="${jdbc.min}" />
</bean>

資料來源2

<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource" scope="singleton">
        <property name="username" value="${jdbc.username2}" />
        <property name="password" value="${jdbc.password2}" />
        <property name
="url" value="${jdbc.url2}" /> <property name="initialSize" value="${jdbc.init2}" /> <property name="maxActive" value="${jdbc.max2}" /> <property name="minIdle" value="${jdbc.min2}" /> </bean>

3.自定義一個數據源類,該類繼承 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
並重寫determineCurrentLookupKey()方法
3.1程式碼如下

public class RoutingDataSource extends AbstractRoutingDataSource  {

     @Override
     protected Object determineCurrentLookupKey() {
            return DataSourceHolder.getDataSourceType();
     }

}

3.2將該類交由sping管理,其在spring配置檔案中配置如下

<bean id="dataSource" class="com.coe.exp.core.dataSource.RoutingDataSource">
        <!-- 為targetDataSources注入兩個資料來源 -->
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="ds1" value-ref="dataSource1"/>
                <entry key="ds2" value-ref="dataSource2"/>
            </map>
        </property>
        <!-- 為指定資料來源RoutingDataSource注入預設的資料來源-->
         <property name="defaultTargetDataSource" ref="dataSource1"/>
    </bean>

3.3spring其他的配置如下

<!-- MyBatis配置 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 把dataSource注入給sqlSessionFactory -->
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.coe.exp.core.ent" />
        <!-- 指定mapper.xml的位置 -->
        <property name="mapperLocations" >
                <array>
                    <value>classpath:com/coe/exp/core/xml/**/*.xml</value>
                    <value>classpath:com/coe/exp/xml/**/*.xml</value>
            </array>
        </property>
        <!-- 指定myBatis配置檔案的位置 -->
        <property name="configLocation" value="classpath:mybatis/sqlmapconfig.xml" />
    </bean>


    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.coe.exp.core.mapper,com.coe.exp.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>

    <!-- 配置事務管理器 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
         <tx:attributes>
             <tx:method name="insert*" propagation="REQUIRED"/>
             <tx:method name="save*" propagation="REQUIRED"/>
             <tx:method name="update*" propagation="REQUIRED"/>
             <tx:method name="delete*" propagation="REQUIRED"/>
             <tx:method name="remove*" propagation="REQUIRED"/>
             <tx:method name="add*" propagation="REQUIRED"/>
             <tx:method name="find*" propagation="SUPPORTS"/>
             <tx:method name="get*" propagation="SUPPORTS"/>
         </tx:attributes>
     </tx:advice>

     <aop:config>
         <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.coe.exp.dao..*Impl.*(..))" order="2"/>
         <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.coe.exp.core.dao..*Impl.*(..))" order="3"/>
     </aop:config>

    <!-- 註解方式配置事物   -->
    <tx:annotation-driven transaction-manager="transactionManager" />

<!-- 引入屬性檔案 -->
    <context:property-placeholder location="classpath:config.properties" />
    <!-- 自動掃描(自動注入) -->
    <context:component-scan base-package="com.coe.exp,mm" annotation-config="true">  
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <context:component-scan base-package="com.coe,mm"/>  
    <!-- 自動掃描定時任務 -->
    <task:annotation-driven/> 
    <!-- spring自動建立代理,植入切面,proxy-target-class屬性,預設為false,表示使用jdk動態代理織入增強,當配為<aop:aspectj-autoproxy  
    poxy-target-class="true"/>時,表示使用CGLib動態代理技術織入增強。不過即使proxy-target-class設定為false,如果目標類沒有宣告介面,則spring將自動使用CGLib動態代理。 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <import resource="../shiro/spring-shiro.xml"/>

4.編寫一個數據源持有類DataSourceHolder

public class DataSourceHolder {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); 

    /**
     * @Description: 設定資料來源型別
     * @param dataSourceType  資料庫型別
     * @return void
     * @throws
     */ 
    public static void setDataSourceType(String dataSourceType) { 
        contextHolder.set(dataSourceType); 
    } 

    /**
     * @Description: 獲取資料來源型別
     * @param 
     * @return String
     * @throws
     */ 
    public static String getDataSourceType() { 
        return contextHolder.get(); 
    } 

    /**
     * @Description: 清除資料來源型別
     * @param 
     * @return void
     * @throws
     */ 
    public static void clearDataSourceType() { 
        contextHolder.remove(); 
    }
}

5.自定義註解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.stereotype.Component;

/**
 * 資料來源
 * 
 * @author llb 2017-03-30
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface DataSource {

    String value() default "";

}

6.動態切換資料來源

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Repository;

import com.coe.exp.core.dataSource.DataSourceHolder;


@Order(1)
@Aspect  
@Repository
public class DataSourceAspect {

    @Pointcut("execution(* com..dao..*Impl.*(..))")
    private void anyMethod() {  
    }

    @AfterReturning(value = "anyMethod()", returning = "result")  
    public void afterReturning(JoinPoint joinPoint,Object result){
        DataSourceHolder.clearDataSourceType();
    }

    @Before(value="anyMethod()")
    public void before(JoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();  
        Method method = methodSignature.getMethod();  
        //如果方法體上使用了DataSource註解
        if (method.isAnnotationPresent(DataSource.class)) {
            //獲取該方法上的註解名
            DataSource datasource = method.getAnnotation(DataSource.class);
            //將方法體上的註解的值賦予給DataSourceHolder資料來源持有類
            DataSourceHolder.setDataSourceType(datasource.value());
        }
    }

}

7.若方法體上沒有註解,則都是使用預設資料來源,如果有以下註解,則使用指定的資料來源

/**
     * 查詢哲盟資料庫中所有狀態正常的客戶餘額
     * @return
     * @author mxl
     * @version 2017年8月16日下午1:30:06
     */
    @DataSource("ds2")
    public List<CustomerBalanceEnt> getAllCustBalanceByZm(){
        return customerBalanceMapper.getAllCustBalanceByZm();
    }

上面這個方法就是使用“ds2”;

相關推薦

Spring配置個數實現資料來源動態切換

1.首先在config.properties檔案中配置兩個資料庫連線的基本資料。這個省略了 2.在spring配置檔案中配置這兩個資料來源: 資料來源1 <!-- initialSize初始化時建立物理連線的個數0 maxActive最大

Spring cloud整合Reids 配置個數

首先是連線池的選擇 一般有兩種 lettuce ,jedis Jedis  執行緒不安全,方法同步 Lettuce  基於Netty.nio, 方法非同步 執行緒 安全 letture通過引入spring-boot-starter-redis就可以使用 <

spring 如何實現注入個數並且可以同時使用這個數

source address: http://bbs.ibeifeng.com/simple/index.php?t16636.html 如何在spring框架中解決多資料來源的問題[轉貼] 在我們的專案中遇到這樣一個問題:我們的專案需要連線多個數據庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資

一個程式配置個數,進行資料來源切換

1>.在資料庫連接配置檔案中配置,資料庫連線資訊,資料來源選擇器,多個數據源資訊,sql會話工廠 <!-- 在applicationContext-dao.xml引入資料庫資訊配置檔案db.properties --> <bean id="prope

AngularJS $q 和 $q.all 單個數個數(promise的說明)

獲取 lar debug let index 被拒 可用 第一個 brush 這篇文章講的不錯, angular $q 和 promise!! -------------------------------------------------------------- 通

EJB 配置個數

name XML cti kong 添加 local ima 不能 transacti 1.修改jboss-6.simple\server\default\deploy\transaction-jboss-beans.xml 配置文件 <bean name="Co

mybatis+druid+springboot 註解方式配置個數

pat nts println service ssp bsp manager 打開 iba 1\數據庫配置 #test數據源 spring.datasource.test.url=jdbc:mysql://*:3306/db?useUnicode=true&ch

Mybatis配置個數

1.編寫2個以上資料來源 <bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">         <property n

hibernate配置個數及事物(以兩個資料來源為例)

在ssh專案中,需要連線兩個不同ip下的資料庫,所以必須要給hibernate配置兩個或多個數據源 因為我只有一臺電腦,所以我配置的是sqlserver+mysql兩個資料來源 首先hibernate配置是直接從myeclipse中新增的   右鍵----myeclipse

Springboot 配置個數(AOP實現分庫)

//因為DynamicDataSource是繼承與AbstractRoutingDataSource,而AbstractRoutingDataSource又是繼承於AbstractDataSource,AbstractDataSource實現了統一的DataSource介面,

tomcat配置個數

應用場景:                公司tomcat伺服器中執行著多個工程,工程連結的mysql資料庫不同,所以每個工程的Spring總配置檔案中都配置了資料來源。 需求:   將資料來源統一拿到tomcat中配置。              本來指派給本人,由於開發

spring 訪問個數(jdbcUrl寫死)

1.資料來源配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="

SpringBoot如何整合個數看這篇就夠了

SpringBoot現在是很多很多公司應用的後端框架,因為它搭建快,能更好、更快速的整合其他第三方。那麼隨著業務的不斷擴充套件,業

Spring管理Hibernate連線個數配置檔案

在這個配置中第一個property屬性配置目標資料來源,<map key-type="java.lang.String">中的key-type必須要和靜態鍵值對照類DataSourceMap中的值的型別相同;<entry key="Yxh" value-ref="yxhDataSource"

使用spring boot 改造老專案個數問題

     使用spring boot 改造老專案,因為資料來源有多個,啟動時一直報如下錯誤 Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifyin

Spring Boot實現個數教程收集(待實踐)

get shu 多個 href eos net -c smi tar 先收集,後續實踐。 http://blog.csdn.net/catoop/article/details/50575038 http://blog.csdn.net/neosmith/article

Spring Profile和Mybatis進行個數(H2和Mysql)的切換

sql pda 開箱 https tails val 收集 sqlserver jpetstore 總結: 最近在做WebMagic的後臺,遇到一個問題:後臺用到了數據庫,本來理想情況下是用Mysql,但是為了做到開箱即用,也整合了一個嵌入式數據庫H2。這裏面就有個問題了,

Redis實現key過期監聽操作redis的個數整合到SpringBoot

最近來了個新的需求,需要使用定時器完成,本想以為用個@Scheduled()就輕易搞定的,詳細瞭解後,事情卻並沒有這麼簡單......。所以接到需求後,需要找產品明確明確再次明確,才開工,不然的話你本以為做好的工作卻是一場空。 業務場景邏輯解析:第一個請求進來,需要把請求引

mybatis如何配置使用個數(environment)?

mybatis如何配置使用多個數據源? 一、資料庫連線properties配置檔案,兩個資料來源的地址: hd.jdbc.driverClassName=com.mysql.jdbc.Driver hd.jdbc.url=jdbc:mysql:/

spring + mybatis 同時連線個數

本文所述是,在一個Spring+mybatis的工程內,需要連線oracle+sqlserver(兩個不同的sqlserver資料庫)。 直接提供配置檔案 <!--<!– 自動掃描 –>--> <context:component-sc