天天看點

springcloud項目接入雙資料源

如果你有一個需求需要查詢多個不同庫的資料,而你又不想建構多個微服務通過feign接口調用的話,那該怎麼辦呢?

答案是那就直接接入多資料源源呗,springcloud整合多資料源非常的簡單,如果你是同一個team裡又隻是個管理背景項目的話,想尋求速度的話可以考慮在單項目裡接入多資料源。

筆者就曾經遇到此類需求,一個管理配置背景需要讀取不同資料源,  
因為開發時間問題,且不想耗費伺服器資源,  
我選擇在項目裡接入雙資料源,下面為大家講解一下如何快速實作  
           
  • 首先注入相關maven依賴如下,這裡我選擇的是性能較好springboot預設HikariCP作為連接配接池
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.2</version>
		<exclusions>
			<exclusion>
				<groupId>org.apache.tomcat</groupId>
				<artifactId>tomcat-jdbc</artifactId>
			</exclusion>
		</exclusions>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>com.zaxxer</groupId>
	<artifactId>HikariCP</artifactId>
	<version>3.2.0</version>
</dependency>

           
  • 新增一個資料源配置類,這裡我和啟動類放在同一個package

    這裡注冊了2個datasource: firstDataSource 和 secondDataSource

    通過@Primary和@Qualifier指定具體使用哪一個

    資料源具體配置待會會介紹

    定義2個不同Configuration對象加載2個不同SqlSessionFactory執行個體,包含配置檔案、資料源、事務等

/**
 * @Description:    資料源配置
 * @Author:         elegant
 * @CreateDate:     2019/11/30 23:32
 * @Version:        1.0
 */
@Configuration
public class DataSourceConfig {

    @Primary
    @Bean(name = "firstDataSource")
    @ConfigurationProperties(value = "spring.datasource.first", ignoreInvalidFields = true)
    public DataSource firstDataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Configuration
    @MapperScan(basePackages = {"com.elegant.test.dao.first"},
            sqlSessionFactoryRef = "firstSqlSessionFactory")
    public static class NewMybatisConfig {
        private DataSource dataSource;

        public NewMybatisConfig(@Qualifier("firstDataSource") DataSource dataSource) {
            this.dataSource = dataSource;
        }

        @Bean(name = "firstSqlSessionFactory")
        public SqlSessionFactory firstSqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource);
            Resource[] mapperLocations = new PathMatchingResourcePatternResolver()
                    .getResources("classpath*:/mapper/first/*.xml");
            factoryBean.setMapperLocations(mapperLocations);
            return factoryBean.getObject();
        }

        @Bean(name = "firstSqlSessionTemplate")
        public SqlSessionTemplate firstSqlSessionTemplate() throws Exception {
            return new SqlSessionTemplate(firstSqlSessionFactory());
        }

        @Bean(name = "firstTransactionManager")
        public PlatformTransactionManager firstTransactionManager() {
            return new DataSourceTransactionManager(dataSource);
        }
    }

    @Bean(name = "secondDataSource")
    @ConfigurationProperties(value = "spring.datasource.second", ignoreInvalidFields = true)
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Configuration
    @MapperScan(basePackages = {"com.elegant.test.dao.second"}, sqlSessionFactoryRef = "secondSqlSessionFactory")
    public static class OldMybatisConfig {
        private DataSource dataSource;

        public OldMybatisConfig(@Qualifier("secondDataSource") DataSource dataSource) {
            this.dataSource = dataSource;
        }

        @Bean(name = "secondSqlSessionFactory")
        public SqlSessionFactory secondSqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource);
            Resource[] mapperLocations = new PathMatchingResourcePatternResolver()
                    .getResources("classpath*:/mapper/second/*.xml");
            factoryBean.setMapperLocations(mapperLocations);
            return factoryBean.getObject();
        }

        @Bean(name = "secondSqlSessionTemplate")
        public SqlSessionTemplate secondSqlSessionTemplate() throws Exception {
            return new SqlSessionTemplate(secondSqlSessionFactory());
        }

        @Bean(name = "secondTransactionManager")
        public PlatformTransactionManager secondTransactionManager() {
            return new DataSourceTransactionManager(dataSource);
        }
    }
}
           
  • 配置檔案指定mybatis配置檔案和對象PO位置, 在新的dao層按此路徑下新增first和second 2個資料源的配置檔案就PO對象就行了
mybatis:
  mapper-locations: classpath:mapper/**/*.xml
  type-aliases-package: com.elegant.test.dao.po
           
  • 接下來搞定2個資料庫的配置就OK了
############################################################################################################

############################################################################################################
# first datasource配置
############################################################################################################
spring.datasource.first.jdbc-url = ${elegant-center.spring.datasource.first.jdbc-url}
spring.datasource.first.username = ${elegant-center.spring.datasource.first.username}
spring.datasource.first.password = ${elegant-center.spring.datasource.first.password}
spring.datasource.first.driver-class-name = com.mysql.jdbc.Driver

spring.datasource.first.type = com.zaxxer.hikari.HikariDataSource
spring.datasource.first.hikari.minimum-idle = 10
spring.datasource.first.hikari.maximumPoolSize = 40
spring.datasource.first.hikari.pool-name = elegant-first-hikariCP
spring.datasource.first.hikari.connection-test-query = SELECT 1
spring.datasource.first.hikari.dataSourceProperties.cachePrepStmts = true
spring.datasource.first.hikari.dataSourceProperties.prepStmtCacheSize = 250
spring.datasource.first.hikari.dataSourceProperties.prepStmtCacheSqlLimit = 2048
spring.datasource.first.hikari.dataSourceProperties.useServerPrepStmts = true
spring.datasource.first.hikari.dataSourceProperties.leak-detection-threshold = 4000

# second datasource配置
############################################################################################################
spring.datasource.second.jdbc-url = ${elegant-center.spring.datasource.second.jdbc-url}
spring.datasource.second.username = ${elegant-center.spring.datasource.second.username}
spring.datasource.second.password = ${elegant-center.spring.datasource.second.password}
spring.datasource.second.driver-class-name = com.mysql.jdbc.Driver

spring.datasource.second.type = com.zaxxer.hikari.HikariDataSource
spring.datasource.second.hikari.minimum-idle = 10
spring.datasource.second.hikari.maximumPoolSize = 40
spring.datasource.second.hikari.pool-name = second-hikariCP
spring.datasource.second.hikari.connection-test-query = SELECT 1
spring.datasource.second.hikari.dataSourceProperties.cachePrepStmts = true
spring.datasource.second.hikari.dataSourceProperties.prepStmtCacheSize = 250
spring.datasource.second.hikari.dataSourceProperties.prepStmtCacheSqlLimit = 2048
spring.datasource.second.hikari.dataSourceProperties.useServerPrepStmts = true
spring.datasource.second.hikari.dataSourceProperties.leak-detection-threshold = 4000

           
  • 啟動我們的應用效果如圖
springcloud項目接入雙資料源