1、枚举多数据源-定义一一对应变量

/**
*
* 列出所有的数据源key(常用数据库名称来命名)
* 注意:
* 1)这里数据源与数据库是一对一的
* 2)DatabaseType中的变量名称就是数据库的名称
*/

public enum DatabaseType {
  test1,test2
}

2、将数据源变量保存在线程变量中

/**
*  
* 作用:1、保存一个线程安全的DatabaseType容器
*/
public class DatabaseContextHolder {

//将数据源枚举变量保存在线程变量中
private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<DatabaseType>();

public static void setDatabaseType(DatabaseType type) {
contextHolder.set(type);
}

public static DatabaseType getDatabaseType() {
return contextHolder.get();
}
}

3、动态数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
*  动态数据源(需要继承AbstractRoutingDataSource)
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getDatabaseType();
}
}

4、数据源配置

数据源1:

test1.driverClassName=org.postgresql.Driver
test1.url=jdbc:postgresql://localhost:5432/test1
test.username=test1

test1.password=123456

test1.remove-abandoned=true
test1.remove-abandoned-timeout=120
test1.test-on-borrow=true

数据源2:

test2.driverClassName=org.postgresql.Driver
test2.url=jdbc:postgresql://localhost:5432/test2
test2.username=test2

test2.password=123456

test2.remove-abandoned=true
test2.remove-abandoned-timeout=120
test2.test-on-borrow=true

5、数据源初始化

/**
* springboot集成mybatis的基本入口
* 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
* 2)创建SqlSessionFactory
* 3)配置事务管理器,除非需要使用事务,否则不用配置
*
*/
@Configuration // 该注解类似于spring配置文件
@MapperScan(basePackages = "cn.test.mapper")
public class MyBatisConfig {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private Environment env;

@Bean
public DataSource test1DataSource() throws Exception {
Properties props = new Properties();
props.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, env.getProperty("test1.driverClassName"));
props.put(DruidDataSourceFactory.PROP_URL, env.getProperty("test1.url"));
props.put(DruidDataSourceFactory.PROP_USERNAME, env.getProperty("test1.username"));

// 获取数据库密码
props.put(DruidDataSourceFactory.PROP_PASSWORD, env.getProperty("test1.password"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONED, env.getProperty("test1.remove-abandoned"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONEDTIMEOUT, env.getProperty("test1.remove-abandoned-timeout"));
props.put(DruidDataSourceFactory.PROP_TESTONBORROW, env.getProperty("test1.test-on-borrow"));
return DruidDataSourceFactory.createDataSource(props);
}

@Bean
public DataSource test2DataSource() throws Exception {
Properties props = new Properties();
props.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, env.getProperty("test2.driverClassName"));
props.put(DruidDataSourceFactory.PROP_URL, env.getProperty("test2.url"));
props.put(DruidDataSourceFactory.PROP_USERNAME, env.getProperty("test2.username"));

// 获取数据库密码 
props.put(DruidDataSourceFactory.PROP_PASSWORD, env.getProperty("test2.password"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONED, env.getProperty("test2.remove-abandoned"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONEDTIMEOUT, env.getProperty("test2.remove-abandoned-timeout"));
props.put(DruidDataSourceFactory.PROP_TESTONBORROW, env.getProperty("test2.test-on-borrow"));
return DruidDataSourceFactory.createDataSource(props);
}

/**
* @throws Exception
* @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
* @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
*/
@Bean
@Primary
public DynamicDataSource dataSource() throws Exception {
DataSource dataSource1 = test1DataSource();

DataSource dataSource2 = test2DataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DatabaseType.test1, dataSource1);

targetDataSources.put(DatabaseType.test2, dataSource2);

DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
dataSource.setDefaultTargetDataSource(dataSource1 );// 默认的datasource设置为dataSource 1
return dataSource;
}

/**
* 根据数据源创建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);// 指定数据源(这个必须有,否则报错)
// 加载配置mybatis-config
DefaultResourceLoader configResourceLoader = new DefaultResourceLoader();
Resource configResource = configResourceLoader.getResource("mybatis-config.xml");
bean.setConfigLocation(configResource);
// 添加mapper文件XML目录
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:cn/test/mapper/*.xml");
bean.setMapperLocations(resources);

return bean.getObject();
}

/**
* 配置事务管理器
*/
@Bean
public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}

}

6、

①查询test1的数据时,可以直接调用对应的mapper;(因为test1是默认数据源)

②查询test2的数据时,需要在调用之前指定数据源,如下代码:

DatabaseContextHolder.setDatabaseType(DatabaseType.test2);

③同时需要查询test1和test2的数据时,需要在调用之前指定正确的数据源。

SpringCloud多数据源实现的更多相关文章

  1. SpringBoot+SpringCloud+vue+Element开发项目——集成Druid数据源

    添加依赖 pom.xml <!--druid--> <dependency> <groupId>com.alibaba</groupId> <ar ...

  2. SpringCloud里面切换数据源无效的问题

    问题描述: 调用链:controller1的接口A->service1的方法A->service2的方法B 方法A开启了事务,且指定了数据库A的数据源 方法B也开启了事务,使用了默认的事务 ...

  3. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

    读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...

  4. 深入理解SpringCloud之配置刷新

    我们知道在SpringCloud中,当配置变更时,我们通过访问http://xxxx/refresh,可以在不启动服务的情况下获取最新的配置,那么它是如何做到的呢,当我们更改数据库配置并刷新后,如何能 ...

  5. Fescar(Seata)-Springcloud流程分析-1阶段

    Fescar是阿里18年开源的分布式事务的框架.Fescar的开源对分布式事务框架领域影响很大.作为开源大户,Fescar来自阿里的GTS,经历了好几次双十一的考验,一经开源便颇受关注.今天就来看了F ...

  6. SpringCloud(1)---基于RestTemplate微服务项目案例

    基于RestTemplate微服务项目 在写SpringCloud搭建微服务之前,我想先搭建一个不通过springcloud只通过SpringBoot和Mybatis进行模块之间额通讯.然后在此基础上 ...

  7. SpringCloud(7)服务链路追踪Spring Cloud Sleuth

    1.简介 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案,并且兼容支持了 zipkin,你只需要在pom文件中引入相应的依赖即可.本文主要讲述服务追踪组件zipki ...

  8. 基于idea的springcloud的helloworld项目搭建过程整理

    Springcloud的搭建主要包括三个部分:服务注册中心.服务提供者.服务消费者.每一个部分都是一个springboot项目,它们通过配置文件(application.properties或appl ...

  9. SpringCloud系列十:SpringCloudConfig 高级配置(密钥加密处理(JCE)、KeyStore 加密处理、SpringCloudConfig 高可用机制、SpringCloudBus 服务总线)

    1.概念:SpringCloudConfig 高级配置 2.具体内容 在 SpringCloudConfig 之中考虑到所有配置文件都暴露在远程仓库之中的安全性问题,所以提供有安全访问的处理机制,这样 ...

随机推荐

  1. mybatis多对一与一对多

    步骤: 1.创建maven项目 2.编写工具类 3.编写实体类 4.编写mapper接口 5.配置xml 6.测试 多对一:多个学生关联一个老师 工具类: //sqlSessionFactory -- ...

  2. React:Lifting State Up

    在学习React的组件的时候,我也好奇组件间需要共享状态或通信的时候,React是如何处理的.在文档的QUICK START的提到Lifting State Up(状态提升),并不是什么新鲜东西.只是 ...

  3. Kappa(cappa)系数只需要看这一篇就够了,算法到python实现

    1 定义 百度百科的定义: 它是通过把所有地表真实分类中的像元总数(N)乘以混淆矩阵对角线(Xkk)的和,再减去某一类地表真实像元总数与被误分成该类像元总数之积对所有类别求和的结果,再除以总像元数的平 ...

  4. MySQL用户、库、表(单/多)操作

    用户及权限操作: 管理员登录:mysql -uroot -p 用户设置密码:set password=password(密码); 查看数据库所有用户:select * from mysql.user; ...

  5. docker基本维护命令

    docker search centos ##查服务器上面的镜像:docker images ##查本地的镜像.docker pull centos ##拉镜像. docker run centos ...

  6. Mysql快速入门(看完这篇能够满足80%的日常开发)

    这是一篇mysql的学习笔记,整理结合了网上搜索的教程以及自己看的视频教程,看完这篇能够满足80%的日常开发了. 菜鸟教程:https://www.runoob.com/mysql/mysql-tut ...

  7. 【Java】Scanner类nextInt后使用nextLine无法读取输入

    首先,我们先介绍一下,在学习Java语言,对于字符串的输入,由于Scanner.next()函数无法输入空格及回车,此时,我们就必须要用Scanner.nextLine()解决这类问题, 在使用过程中 ...

  8. Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)

    好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名<Angular单页面应用基于Ocelot API网关与IdentityServer4+ASP.NET Iden ...

  9. vue-cli中的index.html ,main.js , App.vue的关系

    ###发现不少小伙伴才刚开始接触到这个结构都被绕的迷糊,而发现很多人说的也不是那么准确,那么下面我来说一下是怎么回事### 1.首先我们来看看原生Vue中组件的写法, 我们按照vue-cli的结构按照 ...

  10. Docker入门 安装Tomcat以及报404解决方案

    时间:2020/1/18 17:34:09 浏览:24 来源:互联网 记录简单的在Docker 上安装Tomcat 首先我是在云服务器上(Centos系统)安装的Docker,我们需要在https:/ ...