springboot 配置多数据源

1. application.yml 配置

datasource:
  type: com.alibaba.druid.pool.DruidDataSource
  druid:
    znz:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://ip:3306/znz?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
      username: username
      password: password
    big:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://ip:3306/bg_data1?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
      username: username
      password: password
    maxActive: 20
    initialSize: 1
    maxWait: 60000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20
    stat-view-servlet:
      enabled: true
      url-pattern: /druid/*

    filter:
      stat:
        log-slow-sql: true
        slow-sql-millis: 1000
        merge-sql: true
      wall:
        config:
          multi-statement-allow: true
yml配置

 2.代码

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @version 数据源AOP
 * @Date 2019/04/23
 */
@Component
@Aspect
public class DataSourceAspect implements Ordered {
    public static final Log log = LogFactory.getLog(DataSourceAspect.class);

    /**
     * @version 定义aop作用的注解
     * @Date 2019/04/23
     */
    @Pointcut("@annotation(com.abcdpower.x.zcdatamanagement.common.dataSource.MyDataSource)")//注意:这里的xxxx代表的是上面public @interface DataSource这个注解DataSource的包名
    public void dataSourcePointCut() {

    }

    /**
     * @version 执行前方法
     * @Date 2019/04/23
     */
    @Before("dataSourcePointCut()")
    public void around(JoinPoint point) throws Throwable {
        // 获取MethodSignature
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 获取method
        Method method = signature.getMethod();
        // 获取数据源的注解
        MyDataSource ds = method.getAnnotation(MyDataSource.class);
        // 默认数据源znz
        if (ds == null) {
            DynamicDataSource.setDataSource(DataSourceNames.znz);
        } else {
            // 爬虫数据源
            DynamicDataSource.setDataSource(DataSourceNames.bgData);
        }
    }

    /**
     * @version 释放数据源
     * @Date 2019/04/23
     */
    @After("dataSourcePointCut()")
    public void release() {
        DynamicDataSource.clearDataSource();
    }

    /**
     * @version 设置执行顺序
     * @Date 2019/04/23
     */
    @Override
    public int getOrder() {
        return 1;
    }
}
DataSourceAspect
/**
 * @version 数据源常量
 * @Date 2019/04/23
 */
public interface DataSourceNames {
    String znz = "znz"; // 默认数据源
    String bgData = "big"; // 爬虫数据源
}
DataSourceNames
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @version 存储数据源
 * @Date 2019/04/23
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    // 用来保存数据源与获取数据源
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

    public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource); // 设置默认数据源
        super.setTargetDataSources(new HashMap<Object, Object>(targetDataSources)); // 设置目标数据源
        super.afterPropertiesSet();
    }

    /**
     * @version 获取数据源
     * @Date 2019/04/23
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return getDataSource();
    }

    /**
     * @version 设置数据源
     * @Date 2019/04/23
     */
    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    /**
     * @version 获取数据源
     * @Date 2019/04/23
     */
    public static String getDataSource() {
        return contextHolder.get();
    }

    /**
     * @version 清除数据源
     * @Date 2019/04/23
     */
    public static void clearDataSource() {
        contextHolder.remove();
    }
}
DynamicDataSource
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
import java.util.HashMap;
import java.util.Map;

/**
 * @version 数据源配置类
 * @Date 2019/04/23
 */
@Configuration
public class DynamicDataSourceConfig {

    /**
     * @version 默认数据源
     * @Date 2019/04/23
     */
    @Primary
    @Bean
    @ConfigurationProperties("spring.datasource.druid.znz")
    public DataSource znzDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * @version 爬虫数据源
     * @Date 2019/04/23
     */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.big")
    public DataSource bgDataDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * @version 数据源Map
     * @Date 2019/04/23
     */
    @Bean(name = "dynamicDataSource")
    public DynamicDataSource dataSource(@Qualifier("znzDataSource") DataSource znzDataSource, @Qualifier("bgDataDataSource") DataSource bgDataDataSource) {
        // 新建数据源map
        Map<String, DataSource> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceNames.znz, znzDataSource); // 今日园商
        targetDataSources.put(DataSourceNames.bgData, bgDataDataSource); // 爬虫
        // 返回DynamicDataSource
        return new DynamicDataSource(znzDataSource, targetDataSources);
    }

    /**
     * @version SqlSessionFactory
     * @Date 2019/04/23
     */
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); // 实例化SqlSessionFactoryBean
        bean.setDataSource(dynamicDataSource); // 设置数据源
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/**/*Mapper.xml")); // 定义mapper地址
        return bean.getObject();
    }
        /**
     * 配置事务管理器
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }
DynamicDataSourceConfig
import java.lang.annotation.*;

/**
 * @version 数据源注解
 * @Date 2019/04/23
 */
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyDataSource {
    String name() default ""; // 默认为空
}
MyDataSource
posted @ 2020-01-02 13:19  静思,随心  阅读(212)  评论(0编辑  收藏  举报