美文网首页SpringBoot学习
SpringBoot配置多数据源

SpringBoot配置多数据源

作者: weisen | 来源:发表于2018-11-27 14:43 被阅读0次

开发一个SpringBoot2.0项目,能在方法中方便的切换数据库。

一、引入依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.0.0</version>
        </dependency>

       <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </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-configuration-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

二、application.yml中配置数据库信息

spring:
  application:
    name: bd-its-deg-service
  datasource:
    druid:
      pgdw:
        url: jdbc:postgresql://192.168.235.3/dw?characterEncoding=utf-8
        username: root
        password: 123456#
        driverClassName: org.postgresql.Driver
        filters: stat
        maxActive: 100
        initialSize: 5
        maxWait: 60000
        minIdle: 20
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: "SELECT 'x'"
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        maxOpenPreparedStatements: 60
        removeAbandoned: true
        removeAbandonedTimeout: 1800
        logAbandoned: true
      crawl:
        url: jdbc:postgresql://192.168.235.3/crawl?characterEncoding=utf-8
        username: root2
        password: 666666#
        driverClassName: org.postgresql.Driver
        filters: stat
        maxActive: 100
        initialSize: 5
        maxWait: 60000
        minIdle: 20
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: "SELECT 'x'"
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        maxOpenPreparedStatements: 60
        removeAbandoned: true
        removeAbandonedTimeout: 1800
        logAbandoned: true

三、生成对应的数据库bean类DynamicDataSourceConfiguration


@MapperScan(basePackages = "cn.com.bluemoon.bd.service.its.deg.dao")
@Configuration
public class DynamicDataSourceConfiguration {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.druid.pgdw")
    public DataSource dbPgdw() {
        return DruidDataSourceBuilder.create().build();
    }

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


    /**
     * 核心动态数据源
     *
     * @return 数据源实例
     */
    @Bean
    public DataSource dynamicDataSource() {
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        dataSource.setDefaultTargetDataSource(dbPgdw());
        Map<Object, Object> dataSourceMap = new HashMap<>(4);
        dataSourceMap.put(DataSourceKey.DB_PGDW, dbPgdw());
        dataSourceMap.put(DataSourceKey.DB_CRAWL, dbCrawl());
        dataSource.setTargetDataSources(dataSourceMap);
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dynamicDataSource());
        //此处设置为了解决找不到mapper文件的问题
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

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

    /**
     * 事务管理
     *
     * @return 事务管理实例
     */
    @Bean
    public PlatformTransactionManager platformTransactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }

}

四、配置一个枚举类,记录数据库名

public enum DataSourceKey {
    DB_PGDW,
    DB_CRAWL
}

五、配置一个注解,方法中有该注解的会动态切换数据库

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RUNTIME)
public @interface DataSource {
    DataSourceKey value() default DataSourceKey.DB_PGDW;
}

DynamicDataSourceAspect.java

@Aspect
@Order(-1)
@Component
public class DynamicDataSourceAspect {
    private static final Logger LOG = LoggerFactory.getLogger(DynamicDataSourceAspect.class);

    /**
     * 执行方法前更换数据源
     *
     * @param joinPoint        切点
     * @param targetDataSource 动态数据源
     */
    @Before("@annotation(targetDataSource)")
    public void doBefore(JoinPoint joinPoint, DataSource targetDataSource) {
        DataSourceKey dataSourceKey = targetDataSource.value();
        if (dataSourceKey == DataSourceKey.DB_CRAWL) {
            LOG.info(String.format("设置数据源为  %s", DataSourceKey.DB_CRAWL));
            DynamicDataSourceContextHolder.set(DataSourceKey.DB_CRAWL);
        } else {
            LOG.info(String.format("使用默认数据源  %s", DataSourceKey.DB_PGDW));
            DynamicDataSourceContextHolder.set(DataSourceKey.DB_PGDW);
        }
    }

    /**
     * 执行方法后清除数据源设置
     *
     * @param joinPoint        切点
     * @param targetDataSource 动态数据源
     */
    @After("@annotation(targetDataSource)")
    public void doAfter(JoinPoint joinPoint, DataSource targetDataSource) {
        LOG.info(String.format("当前数据源  %s  执行清理方法", targetDataSource.value()));
        DynamicDataSourceContextHolder.clear();
    }

}

DynamicDataSourceContextHolder.java

public class DynamicDataSourceContextHolder {

    private static final ThreadLocal<DataSourceKey> currentDatesource = new ThreadLocal<>();

    /**
     * 清除当前数据源
     */
    public static void clear() {
        currentDatesource.remove();
    }

    /**
     * 获取当前使用的数据源
     *
     * @return 当前使用数据源的ID
     */
    public static DataSourceKey get() {
        return currentDatesource.get();
    }

    /**
     * 设置当前使用的数据源
     *
     * @param value 需要设置的数据源ID
     */
    public static void set(DataSourceKey value) {
        currentDatesource.set(value);
    }

}

DynamicRoutingDataSource.java

public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
    private static final Logger LOG = LoggerFactory.getLogger(DynamicRoutingDataSource.class);
    @Override
    protected Object determineCurrentLookupKey() {
        LOG.info("当前数据源:{}", DynamicDataSourceContextHolder.get());
        return DynamicDataSourceContextHolder.get();
    }
}

具体的类如下图所示


image.png

六、用法

在service方法中添加上配置的注解

    @Override
    @DataSource(DataSourceKey.DB_PGDW)
    public String exportDataTable(String param) {
        log.info("切换数据源为PG dw库 测试是否被调用:" + param + ">>>>>>>>>" + param);
        // 切换数据源为PG dw库
       }

当然,也可以不使用注解,可以在同一个方法中使用不同的数据库

        @Override
    public String exportDataTable(String param) {
                DynamicDataSourceContextHolder.set(DataSourceKey.DB_PGDW);
        log.info("切换数据源为PG dw库 测试是否被调用:" + param + ">>>>>>>>>" + param);
        // 切换数据源为PG dw库
                if(......){
                  DynamicDataSourceContextHolder.set(DataSourceKey.DB_CRAWL);
                }
       }

参考文章:https://blog.csdn.net/u013360850/article/details/78861442

相关文章

网友评论

    本文标题:SpringBoot配置多数据源

    本文链接:https://www.haomeiwen.com/subject/nqjgqqtx.html