天天看点

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项目接入双数据源