Spring整合多数据源实现动态切换

在实际项目中时常需要连接多个数据库,而且不同的业务需求在实现过程当中往往需要访问不同的数据库。

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(多数据源目标)属性的Map映射,使用动态数据源DynamicDataSource是继承与AbstractRoutingDataSource,而AbstractRoutingDataSource又是继承于org.springframework.jdbc.datasource.AbstractDataSource,AbstractDataSource实现了统一的DataSource接口,所以DynamicDataSource同样可以当一个DataSource使用:

   <!-- 数据库连接池配置 -->
     <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" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <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>

     <!-- 动态数据源 -->
     <bean id="dynamicDataSource" class="com.yahu.core.dao.DynamicDataSource">
        <!-- 通过key-value的形式来关联数据源 -->
        <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动态数据源类,扩展Spring的AbstractRoutingDataSource抽象类,实现动态数据源,AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是实现数据源的route的核心.这里对该方法进行Override:

package com.yahu.core.dao;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/*******************************************************************
 * @describe : 建立动态数据源类   必须继承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;
    }

}

获得和设置上下文环境,为一线程安全的ThreadLocal:

package com.yahu.core.dao;

/*******************************************************************
 * @describe : 获得和设置上下文环境
 ********************************************************************/
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();
    }
}

动态数据源的管理,如何选择控制每个业务中需要的具体数据源,可以使用手动控制,业务层通过加入以下代码

CustomerContextHolder.setCustomerType(CustomerContextHolder.DATASOURCE);

即可实现动态切换数据源,如果在service层有比较统一的规则的话,也可以使用aop设置数据源使用,这里一般都是一个service一个数据源,所以最好使用aop在service层执行完之后统一调用

CustomerContextHolder.clearCustomerType();

清空数据源信息。

当然,在上面配置里面有个参数defaultTargetDataSource为默认数据源,就是不设置数据源的话,就是用这个数据源。

时间: 2024-08-24 12:17:50

Spring整合多数据源实现动态切换的相关文章

Spring整合Hibernate_数据源Datasource_dbcp连接池

1,  Spring指定 datasource DataSource接口,在javax.sql包,里边有一个getConnection()方法.提供了标准化的取得连接的方式.只要实现了这个接口.Sun这个土鳖定的. a)         参考文档,找dbcp.BasicDataSource  (dbcp:database connection pool数据库连接池) i.  c3p0 ii.     dbcp iii.    proxool b)        在DAO或者Service中注入d

BIRT统一公用数据源、动态切换数据源解决方案

通过BIRT报表工具开发出来的报表,在运行时往往是走一个统一的生产环境数据源,但是开发时往往是一个开发测试用的数据源,这就 需要随时能够在两个环境下进行切换.目前针对这个问题,公开可检索到的资料,基本上是通过数据源的beforeopen事件,通过写脚本的方式解决,这个 方式还是比较复杂,在报表数量较多,开发人数较多时,开发人员需要注意的地方还是有些多,并不完美.本文的处理方式,将能够根本性的解决该问题. 不能在报表制作上做文章了,这样要么需要大量修改报表文件,要么需要每个报表继承一个公共的库文件

Spring整合quartz实现定时动态任务

在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法可以是普通类.很显然,第二种方式远比第一种方式来的灵活. 这里使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法,实现定时动态任务功能. <bean id="addHandlePayCashApplyToMq" class="org

Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法(转)

一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基本上没有什么问题,但唯一可能出现问题的就是在hibernate做添加操作生成主键策略的时候.因为我们都知道hibernate的数据库本地方言会针对不同的数据库采用不同的主键生成策略. 所以针对这一问题不得不采用自定义的主键生成策略,自己写一个主键生成器的表来维护主键生成方式或以及使用其他的方式来生成

Spring动态切换多数据源解决方案

spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据. Spring2.x以后的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来.Client提供选择所需的上下文(因为

springboot+mybatis实现动态切换数据源

前几天有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源.我上网收集了一些资料整合了一下,虽然最后这个需求不了了之了,但是多数据源动态切换还是蛮好用的,所以记录一下,或许以后有用呢?或者自己感兴趣又想玩呢! 1.加个依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifa

mybatis动态切换数据源

(#)背景:由于业务的需求,导致需要随时切换15个数据源,此时不能low逼的去写十几个mapper,所以想到了实现一个数据源的动态切换 首先要想重写多数据源,那么你应该理解数据源的一个概念是什么,DataSourceTransactionManager这个类就是spring中对于数据源的封装,其中DataSource做为 他的一个成员.接下来我们要介绍一下我们切换动态数据源需要使用的类,AbstractRoutingDataSource,先来看看这个类的源码 首先看看这几个变量,targetDa

springboot多数据源动态切换和自定义mybatis件分页插

1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.datasource.url= jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8 route.datasource.username= root route.datasource.password= 1234

koala 多数据源动态切换

koala 特点:多数据源动态切换,数据源分组和负载均衡(轮询) 项目源码以及demo:https://github.com/zeq9069/koala 请大家关注一下哦!!哈哈! 最近,在开发项目的时候后,要用到多个数据源的动态切换,于是就开发了koala 这个小小得框架,koala支持多数据源的切换,数据源的分组和负载均衡(轮询)! 只需要将jar引入到你自己的项目中之后,然后进行简单配置就可以使用了!!使用起来 非常方便,该项目提供了三个核心的注解@ChangeTo,@DataSource