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”;

---------------------
作者:苹果树上的你
来源:CSDN
原文:https://blog.csdn.net/ll535299/article/details/78203634
版权声明:本文为博主原创文章,转载请附上博文链接!

Spring配置多个数据源,并实现数据源的动态切换转载)的更多相关文章

  1. 多数据源系统接入mybatis-plus, 实现动态数据源、动态事务。

    目录: 实现思想 导入依赖.配置说明 代码实现 问题总结 一.实现思想 接手一个旧系统,SpringBoot 使用的是纯粹的 mybatis ,既没有使用规范的代码生成器,也没有使用 JPA 或者 m ...

  2. Spring配置c3p0数据源时出错报:java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

    今天在使用Spring配置c3p0数据源时,使用的数据库是mysql,服务器是tomcat,运行时报了一个 java.lang.NoClassDefFoundError: com/mchange/v2 ...

  3. Spring配置数据源

    Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0.可以在Spring配置文件中利用这两者中任何一个配置数据源. DBCP数据源 DBCP类包位于 ...

  4. Spring配置数据源的几种形式

    Spring中提供了4种不同形式的数据源配置方式: 1.Spring自带的数据源(DriverMangerDataSource); 2.DBCP数据源; 3.C3P0数据源; 4.JNDI数据源. 以 ...

  5. Spring配置多个数据源

    Spring 配置多数据源实现数据库读写分离 博客分类: Spring 数据库   现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Mast ...

  6. Spring配置DataSource数据源

    在Spring框架中有例如以下3种获得DataSource对象的方法: 1.从JNDI获得DataSource. 2.从第三方的连接池获得DataSource. 3.使用DriverManagerDa ...

  7. Spring配置动态数据源-读写分离和多数据源

    在现在互联网系统中,随着用户量的增长,单数据源通常无法满足系统的负载要求.因此为了解决用户量增长带来的压力,在数据库层面会采用读写分离技术和数据库拆分等技术.读写分离就是就是一个Master数据库,多 ...

  8. 【Spring】19、spring配置数据源的4种方式

    不管采用何种持久化技术,都需要定义数据源.Spring中提供了4种不同形式的数据源配置方式: spring自带的数据源(DriverManagerDataSource),DBCP数据源,C3P0数据源 ...

  9. 使用Spring配置动态数据源实现读写分离

    最近搭建的一个项目需要实现数据源的读写分离,在这里将代码进行分享,以供参考.关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!-- ...

随机推荐

  1. Redhat 7修改主机名

    修改主机名: Linux master2 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017 x86_64 x86_64 x86_64 G ...

  2. 51单片机通过ESP8266模块与手机进行通讯(单片机)

    相关连接和资料下载: 个人博客 资料下载 Step1:配置ESP8266 通过USB转TTL模块把ESP8266模块和电脑连接起来,如图: 把ESP8266模块的VCC,GND,CH_PD,UTXD, ...

  3. Stopwatch简单时间检测

    public ActionResult Index() { Stopwatch sw = new Stopwatch(); //实例化一个对象 sw.Start(); //开始计算 int[] a = ...

  4. html和css牛刀小试

    html和css网上教程很多,这里我也给大家一个网址:https://www.cnblogs.com/majj/ 今天心血来潮就模仿着小米的官网写了部分代码,效果图如下:(本人故意加了个华为广告栏在最 ...

  5. Mysql和ORACLE索引的实现方式

    B-Tree和B+Tree 目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构. 首先,对单个节点来说,是一个key value结构,key是作引的列,value有两种, ...

  6. 多线程之CountDownLatch

    下面请看一个应用场景:有1个driver和5个worker,需要满足以下两点要求: 当driver完成了全部的工作之后才允许worker们开始工作: 当所有的worker都完成了自己的工作之后,dri ...

  7. 【hiho1087】Hamiltonian Cycle

    题目大意:给定一个 N 个点的有向图,计数图上哈密顿回路的条数. 题解:哈密顿回路需要经过除了初始位置,每个点恰好一次.如果已知一条哈密顿回路的方向,那么从这条路上任意一个点出发,得到的都是同样的结果 ...

  8. 记一次生产环境nginx图片上传不了的问题

    在server节点目录下配置: client_max_body_size 8M; client_body_buffer_size 8M; 不过还是不能上传就执行下面这条命令: cd /var/lib/ ...

  9. 关于enter事件的触发

    如果您使用了antd的Button组件,那么恭喜已经封装好了,只要加上htmlType='submit', 如果没有使用其他框架,使用onPress或者onKeydown事件,判断e.keycode ...

  10. JZOJ5358【NOIP2017提高A组模拟9.12】BBQ

    题目 分析 发现,\(C_{ai+aj+bi+bj}^{ai+aj}\),其实就等于从(0,0)走最短路到(ai+aj,bi+bj). 我们可以想办法将i.j分开,从(0,0)走最短路到(ai+aj, ...