1. 程式人生 > 其它 >【Spring boot】雙資料來源/多資料來源 spring boot+druid配置多資料來源詳細配置

【Spring boot】雙資料來源/多資料來源 spring boot+druid配置多資料來源詳細配置

 

1.pom.xml檔案

<spring.boot.version>2.2.5.RELEASE</spring.boot.version>
<mysql-connector-java-version>6.0.6</mysql-connector-java-version>
<alibaba-druid-version>1.1.10</alibaba-druid-version>

<dependencies>
        <dependency>
            <groupId>
org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <
groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> </dependencies>

 

 

 

2.啟動類

// 這個就不需要在啟動類加了,相比較單資料來源  @MapperScan("com.swapping.dao.mapper.mysql")
@SpringBootApplication
@ComponentScan(basePackages = {"com.swapping.*"})
@Slf4j
public class SwappingApiApplication {

    public static void main(String[] args) {
        try {
            SpringApplication.run(SwappingApiApplication.class, args);
            System.out.println("SwappingApiApplication 啟動成功......");
        } catch (Exception e) {
            log.error("SwappingApiApplication 啟動失敗", e);
        }
    }
}

 

 

3.yml配置檔案

 

yml配置檔案如下,雙資料來源如下,多資料來源就往下加配置就行
注意:相比較單資料來源,應該用jdbc-url做key,否則會有執行時異常 多資料來源java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
${my_first_mysql.host} 或 ${my_sencond_tidb.host} 可以是配置檔案取的配置,也可以像username一樣直接寫死,都可以

 

# 驅動配置資訊
spring:
  datasource:
    my-first-mysql:
      #連線池的配置資訊
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      druid:
        filters:
        max-active: 16
        initial-size: 2
        max-wait: 3000
        minIdle: 2
        time-between-eviction-runsMillis: 60000
        min-evictable-idle-timeMillis: 300000
        validation-query: SELECT 1
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: false
        max-open-prepared-statements: -1
      jdbc-url: jdbc:mysql://${my_first_mysql.host}:${my_first_mysql.port}/my_first_mysql_dbName?characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=GMT%2B8&connectTimeout=2000&socketTimeout=150000
      username: XXX
      password: XXX
    my-sencond-tidb:
      #連線池的配置資訊
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      druid:
        filters:
        max-active: 16
        initial-size: 2
        max-wait: 3000
        minIdle: 2
        time-between-eviction-runsMillis: 60000
        min-evictable-idle-timeMillis: 300000
        validation-query: SELECT 1
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: false
        max-open-prepared-statements: -1
      jdbc-url: jdbc:mysql://${my_sencond_tidb.host}:${my_sencond_tidb.port}/my_sencond_mysql_dbName?characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=GMT%2B8&connectTimeout=2000&socketTimeout=150000
      username: XXX
      password: XXX

 

 

4.自定義DataSourceConfig

自定義DataSourceConfig,而不用Springboot自啟動的DataSourceConfig。
兩個資料來源就定義兩個,多個數據源就定義多個
如果重點2沒有區分各資料來源的包掃描路徑,會有執行時異常:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

 

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;


/**
 * 第一個資料來源
 *
 * @author xudong.shen
 * @date 2022/04/16
 */
@Configuration
@MapperScan(basePackages = "com.swapping.dao.mapper.mysql", sqlSessionTemplateRef  = "sqlSessionTemplate")//重點1 指定包掃描,當前這個資料來源對應的mapper.java檔案放在哪個包下,這裡路徑就指定哪裡
public class MyFirstDataSourceConfig {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.my-first-mysql")//重點3 這裡對應yml的當前資料來源的字首
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();

    }

    @Bean
    @Primary
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/mysql/*.xml"));//重點2 指定包掃描,當前這個資料來源對應的mapper.xml檔案在哪個resource下的包裡,這裡路徑就指定哪裡
        // bean.setPlugins(new Interceptor[] {xxx}); // 設定MyBatis外掛
        return bean.getObject();
    }


    @Bean
    @Primary
    public DataSourceTransactionManager testTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 第二個資料來源
 *
 * @author xudong.shen
 * @date 2022/04/18
 */
@Configuration
@MapperScan(basePackages = "com.swapping.dao.mapper.tidb", sqlSessionTemplateRef  = "sqlSessionTemplateSecond")//重點1 指定包掃描,當前這個資料來源對應的mapper.java檔案放在哪個包下,這裡路徑就指定哪裡
public class MySecondDataSourceConfig {


   
    @Bean(name = "dataSourceSecond")
    @ConfigurationProperties(prefix = "spring.datasource.my-sencond-tidb")//重點3 這裡對應yml的當前資料來源的字首
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();

    }

    @Bean(name = "sqlSessionFactorySecond")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("dataSourceSecond") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/tidb/*.xml"));//重點2 指定包掃描,當前這個資料來源對應的mapper.xml檔案在哪個resource下的包裡,這裡路徑就指定哪裡
        // bean.setPlugins(new Interceptor[] {xxx}); // 設定mybatis外掛
        return bean.getObject();
    }

    @Bean(name = "transactionManagerSecond")
    public DataSourceTransactionManager testTransactionManager(@Qualifier("dataSourceSecond") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplateSecond")
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("sqlSessionFactorySecond") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 

 

5.Mapper.java 和 Mapper.xml的說明

到這裡,多資料來源的配置層面東西,就全部完成了。
後面的mapper.java  mapper.xml  就放在上面各自資料來源的指定包路徑下,即可。
後面Service呼叫Mapper的動作,就和單資料來源 一樣了。正常呼叫就行了。(當然,跨資料來源了,事務肯定就行不通了!)