spring boot 配置多数据源

荒凉一梦 提交于 2019-12-18 14:53:41

mybatis配置项

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

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


@Configuration
public class MyBatisConfig {

    @Autowired
    private DatabaseProperties databaseProperties;

    /**
     * 本地数据源
     * @return
     */
    public DataSource createMainDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(databaseProperties.getMain().getDriverClassName());
        druidDataSource.setUrl(databaseProperties.getMain().getUrl());
        druidDataSource.setUsername(databaseProperties.getMain().getUsername());
        druidDataSource.setPassword(databaseProperties.getMain().getPassword());
        return druidDataSource;
    }

    /**
     * 远程数据源
     * @return
     */
    public DataSource createIntelligentCabinetDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(databaseProperties.getIntelligentCabinet().getDriverClassName());
        druidDataSource.setUrl(databaseProperties.getIntelligentCabinet().getUrl());
        druidDataSource.setUsername(databaseProperties.getIntelligentCabinet().getUsername());
        druidDataSource.setPassword(databaseProperties.getIntelligentCabinet().getPassword());
        return druidDataSource;
    }


    @Bean
    @Primary
    public DynamicDataSource dataSource() {
        DataSource mainDataSource = createMainDataSource();
        DataSource intelligentCabinetDataSource = createIntelligentCabinetDataSource();

        Map<Object, Object> targetDataSources = new HashMap<>(2);
        targetDataSources.put(DatabaseType.MAIN, mainDataSource);
        targetDataSources.put(DatabaseType.INTELLIGENT_CABINET, intelligentCabinetDataSource);

        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(mainDataSource);

        return dataSource;
    }

    /**
     * 配置事务管理器
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }

}

AbstractRoutingDataSource 根据用户定义的规则选择数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {
     @Override
     protected Object determineCurrentLookupKey() {
         return DatabaseContextHolder.getDatabaseType();

     }
}

配置数据源类型

public enum DatabaseType {

    /**
     * 主数据源
     */
    MAIN,

    /**
     * 
     * 远程数据源
     */
    INTELLIGENT_CABINET

}

数据源配置

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "datasource")
public class DatabaseProperties {

    private MainDatabase main;

    private IntelligentCabinetDatabase intelligentCabinet;

    public MainDatabase getMain() {
        return main;
    }

    public void setMain(MainDatabase main) {
        this.main = main;
    }

    public IntelligentCabinetDatabase getIntelligentCabinet() {
        return intelligentCabinet;
    }

    public void setIntelligentCabinet(IntelligentCabinetDatabase intelligentCabinet) {
        this.intelligentCabinet = intelligentCabinet;
    }
}

/**
 * 主数据源
 */
class MainDatabase {
    private String driverClassName;

    private String url;

    private String username;

    private String password;

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

/**
 * 远程数据源
 */
class IntelligentCabinetDatabase {
    private String driverClassName;

    private String url;

    private String username;

    private String password;

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

配置数据源工具类

public class DatabaseContextHolder {

    private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();

    public static void setDatabaseType(DatabaseType type) {
        contextHolder.set(type);
    }

    public static DatabaseType getDatabaseType() {
        return contextHolder.get();
    }

    public static void resetDatabaseType(){
        contextHolder.set(DatabaseType.MAIN);
    }

}

使用AOP拦截数据源

import com.sunvua.alan.base.datasource.DatabaseContextHolder;
import com.sunvua.alan.base.datasource.DatabaseType;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 多数据源配置
 */
@Aspect
@Order(-1)//一定要配置Order为-1,不然不生效
@Component
public class DataAop {

    @Pointcut("execution(* com..*Service..*(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void pandoraData()  {
        DatabaseContextHolder.setDatabaseType(DatabaseType.INTELLIGENT_CABINET);
    }
    @After("pointcut()")
    public void AvengersData()  {
        DatabaseContextHolder.resetDatabaseType();
    }

}

配置文件

datasource:
  main:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://ip:端口/数据库?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
  intelligentCabinet:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://ip:端口/数据库?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!