nacos添加多数据源配置

1. nacos中添加多数据源配置

spring:
  datasource:
    master:
      url: jdbc:mysql://base-mysql:3306/XXX?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      name: master
      initialize: true
      filters: stat
    slave1:
      url: jdbc:mysql://base-mysql:3306/XXX?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      name: slave1
      initialize: true
      filters: stat

这样就配置好了两个数据源分别为 master和slave1
然后还要去springboot 启动页面添加

之后自定义的数据源的注解

2. 自定义数据源切换注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface DB{
    String value() default "master";
}

3. 数据源切换操作配置

当前线程上下文数据源标识类 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class DynamicDataSourceSwitcher {

    static Logger logger = LoggerFactory.getLogger(DynamicDataSourceSwitcher.class);

    public static final String Mater = "master";
    public static final String Slave1 = "slave1";

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

    public static void setDataSource(String name){
        logger.info("-------- 设置数据源数据源为 :{} ", name);
        contextHolder.set(name);
    }

    public static String getDataSource(){
            if (StringUtils.isEmpty(contextHolder.get())) {
            setDataSource(Mater);
        }
        return contextHolder.get();
    }

    public static void cleanDataSource(){
        contextHolder.remove();
    }

}

动态数据源切换 , 核心就是通过这个类实现多数据源的额动态切换 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


public class DynamicDataSource extends AbstractRoutingDataSource {

    Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);

    @Override
    protected Object determineCurrentLookupKey() {
        logger.info("------------------当前数据源 {}", DynamicDataSourceSwitcher.getDataSource());
        return DynamicDataSourceSwitcher.getDataSource();
    }
}

 多数据源bean的配置类

import com.alibaba.druid.pool.DruidDataSource;
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 javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MultipleDataSourceConfig {

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource createMasterDataSource(){
        return new DruidDataSource();
    }

    @Bean("slave1")
    @ConfigurationProperties(prefix = "spring.datasource.slave1")
    public DataSource createSlave1DataSource(){
        return new DruidDataSource();
    }

    /**
     * 设置动态数据源,通过@Primary 来确定主DataSource
     * @return
     */
    @Bean
    @Primary
    public DataSource createDynamicDataSource(@Qualifier("master") DataSource master, @Qualifier("slave1") DataSource slave1){
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        //设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(master);
        //配置多数据源
        Map<Object, Object> map = new HashMap<>();
        map.put("master",master);
        map.put("slave1",slave1);
        dynamicDataSource.setTargetDataSources(map);
        return  dynamicDataSource;
    }
}

 aop切面实现多数据源切换

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 切换数据源
 * 选择非master数据源时, 通过切面切换数据源
 */
@Aspect
@Component
@Order(1)
public class DynamicDataSourceAspect {
    private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);

    /**
     * 切入点只对@Service注解的类上的@Db注解生效 , 无注解 , 默认使用master
     * @param db
     */
    @Pointcut(value="@within(org.springframework.stereotype.Service) && @annotation(db)" )
    public void dynamicDataSourcePointCut(DB db){}

    @Before(value = "dynamicDataSourcePointCut(db)")
    public void switchDataSource(DB db) {
        DynamicDataSourceSwitcher.setDataSource(db.value());
    }

    /**
     * 切点执行完后 切换成主数据库
     * @param db
     */
    @After(value="dynamicDataSourcePointCut(db)")
    public void after(DB db){
        DynamicDataSourceSwitcher.cleanDataSource();
    }
}

4. 使用

@Override
@DB(value = DynamicDataSourceSwitcher.Slave1)
public List<Map> getUser() {
   return userMapper.getUser();
}

@Override
@DB(value = DynamicDataSourceSwitcher.Master)
public List<Map> getInstrumentList() {
   return instrumentMapper.getInstrumentList();
}

最后 : 

@SpringBootApplication(scanBasePackages = {"org.orient.otc"},exclude = {DataSourceAutoConfiguration.class})
exclude = {DataSourceAutoConfiguration.class}这个东西你不加上(自定义数据源一定要排除SpringBoot自动配置数据源) , 就会在启动项目时报错循环依赖;
 org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration
┌─────┐
|  dataSource
↑     ↓
|  scopedTarget.dataSource defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]
↑     ↓
|  org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker
└─────┘ 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值