1. 程式人生 > 其它 >druid連線池實現多資料來源動態切換方式

druid連線池實現多資料來源動態切換方式

一、繼承介面AbstractRoutingDataSource(mysql)

主要的starter:

  <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>


<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2
.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>

yml中的配置檔案:

server:
  port: 8888
spring:
  datasource:
#    url: jdbc:mysql://127.0.0.1:3306/db01?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false
#    username: root
#    password: 123456
#    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    datasource1:
      url: jdbc:mysql://127.0.0.1:3306/db01?serverTimezone=UTC
&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: 123456 initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver datasource2: url: jdbc:mysql://127.0.0.1:3306/db02?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: 123456 initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver datasource3: url: jdbc:mysql://127.0.0.1:3306/db03?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: 123456 initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver # \u8FD9\u79CD\u65B9\u5F0F\u4E0D\u80FD\u8BBE\u7F6Emybatis plugin #mybatis: # configuration: # interceptors: # - com.tuling.dynamic.datasource.plugin.DynamicDataSourcePlugin

配置檔案:將對應的資料來源配置為Bean,自動管理

@Configuration
public class DynamicDataSourceConfig{

    //定義datasource:因為是資料來源,所以返回結果為DataSource
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.datasource1")
    public DataSource dataSource1(){
        // 底層會自動拿到spring.datasource中的配置, 建立一個DruidDataSource
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.datasource2")
    public DataSource dataSource2(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.datasource3")
    public DataSource dataSource3(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager1(@Qualifier("dataSource1") DataSource dataSource1) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource1);
        return dataSourceTransactionManager;
    }


    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager2(@Qualifier("dataSource2") DataSource dataSource2) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource2);
        return dataSourceTransactionManager;
    }

    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager3(@Qualifier("dataSource3") DataSource dataSource3) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource3);
        return dataSourceTransactionManager;
    }


}

繼承(AbstractRoutingDataSource),並進行配置管理

@Component
//這裡使用@Primary,才會在程式執行過程中最先使用該類
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {

    public static ThreadLocal<String> name = new ThreadLocal<>();

    @Resource
    DataSource dataSource1;
    @Resource
    DataSource dataSource2;
    @Resource
    DataSource dataSource3;
    /**
     * Determine the current lookup key. This will typically be
     * implemented to check a thread-bound transaction context.
     * <p>Allows for arbitrary keys. The returned key needs
     * to match the stored lookup key type, as resolved by the
     * {@link #resolveSpecifiedLookupKey} method.
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return name.get();
    }

    @Override
    public void afterPropertiesSet() {
        // 為targetDataSources初始化所有資料來源
        Map<Object, Object> targetDataSource = new HashMap<>();
        targetDataSource.put("R1", dataSource1);
        targetDataSource.put("R2", dataSource2);
        targetDataSource.put("R3", dataSource3);

        super.setTargetDataSources(targetDataSource);

        //為defaultTargetDataSource 設定預設的資料來源
        super.setDefaultTargetDataSource(dataSource1);

        //返回給父類,父類進行資料來源的初始化和管理
        super.afterPropertiesSet();
    }
}

最後在選擇自己對應的資料來源時,可以根據自己設定的Key值,獲取對應的資料來源連線

@GetMapping("/select1")
    public List<UserInfo> queryUserById01(){
        DynamicDataSource.name.set("R1");//這裡“R1”就表示當前使用的資料來源key為“R1”
        List<UserInfo> userInfos = userService.selectByPrimaryKey();
        return userInfos;
    }