Springboot集成多数据源实现动态切换数据源

1.AbstractRoutingDataSource
这个类提供的determineCurrentLookupKey()可以决定使用的是哪个数据源

2.自定义类继承AbstractRoutingDataSource,并在方法中决定数据源

public class DataSourceSelect {

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

    private static final String dataSourcePrefix="db";

    public static void setDataSource(int key){
        String s = dataSourcePrefix + key;
        contextHolder.set(s);
    }

    public static String getDataSource(){
        return contextHolder.get();
    }

    public static void clear(){
        contextHolder.remove();
    }

}
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        log.info("当前是数据是"+DataSourceSelect.getDataSource());
        return DataSourceSelect.getDataSource();
    }

}

3.application.yml中多数据源的配置

spring:
  application:
    name: test-demo
  datasource:
  	#多数据源时需要写成driver-class-name
    driver-class-name: com.mysql.cj.jdbc.Driver
    #3个数据库配置
    db1:
      #多数据源时需要写成jdbc-url,而不能是url
      jdbc-url: jdbc:mysql://10.250.200.102:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: 123
    db2:
      jdbc-url: jdbc:mysql://10.250.200.103:3306/db2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: 123
    db3:
      jdbc-url: jdbc:mysql://10.250.200.104:3306/db3?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: 123

4.配置代码块

@SpringBootConfiguration
public class DataSourceConfig {

    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource dataSourceOne() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource dataSourceTwo() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "db3")
    @ConfigurationProperties(prefix = "spring.datasource.db3")
    public DataSource dataSourceThree() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默认数据源
		dynamicDataSource.setDefaultTargetDataSource(dataSourceOne());
        // 配置多数据源
        Map<Object, Object> dsMap = new HashMap<>();
        dsMap.put("db1", dataSourceOne());
        dsMap.put("db2", dataSourceTwo());
        dsMap.put("db3", dataSourceThree());

        dynamicDataSource.setTargetDataSources(dsMap);
        return dynamicDataSource;
    }

    /**
     * 配置多数据源后IOC中存在多个数据源了,事务管理器需要重新配置,不然器不知道选择哪个数据源
     * 事务管理器此时管理的数据源将是动态数据源dynamicDataSource
     * 配置@Transactional注解
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dynamicDataSource());
        //多数据源时需要在这里指定xml文件的路径
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return sqlSessionFactoryBean;
    }


}

5.简单的演示

try{
    for(int n=1;n<=9;n++){
         DataSourceSelect.setDataSource(n);
         List<Map<String, Object>> list = visitingMapper.findVisiting();
         if(list.size() == 0){
              log.info("【任务】【结束】【当前需要下发的数据为0条】");
              return;
         }
         log.info("【任务】【进行中】【当前需要下发的数据为{}条】",list.size());
         DataSourceSelect.clear();
    }
}catch (Exception e){
    e.printStackTrace();
}

运行结果: 在这里插入图片描述
6.注意点

  1. application.yml配置文件里
    url要写成jdbc-url
    指定driver-class-name
  2. 启动类上要去除DataSourceAutoConfiguration类
    在这里插入图片描述
  3. 代码中指定xml文件的位置
    在这里插入图片描述
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值