springboot多数据源使用


这里的多数据的使用是定义切面和用注解的方式来实现的,使用的话相对于比较简单,在方法实现上面定义好注解,标明是哪个数据源的即可,不过一个方法不能同时使用多个数据源,要区别开来,可以单独对其他数据源的方法进行封装,处理好再返回即可

1.配置yml文件

这里我的master1和master2数据源都是mysql的,如果想要配置其他的数据源的话,可以自己修改master2,或者master3如此类推。

 datasource:
    master1:
      username: root
      password: tisson123!#
      #password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
      #用测试环境的库
      jdbc-url: jdbc:mysql://116.85.22.202:3307/industrial_park?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
      druid://...............连接池那些,自己搞
    master2:
      username: root
      password: tisson123!#
      #password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
      #用测试环境的库
      jdbc-url: jdbc:mysql://116.85.22.202:3307/business_management?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
      druid:   //.......连接池

2.配置config

DynamicDataSourceConfig

mport cn.tisson.yq.enterprise.common.DynamicDataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;

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

/**
 * 添加此配置,否则 报`The dependencies of some of the beans in the application context form a cycle`
  */
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
@Configuration
@PropertySource("classpath:application.yml")
@MapperScan(basePackages = "cn.tisson.yq.enterprise.dao.mapper")
public class DynamicDataSourceConfig {

    @Bean("master1")
    @ConfigurationProperties(prefix = "spring.datasource.master1")
    public DataSource master1DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("master2")
    @ConfigurationProperties(prefix = "spring.datasource.master2")
    public DataSource master2DataSource() {
        return DataSourceBuilder.create().build();
    }

    //设置动态数据源为主数据源
    @Bean
    @Primary
    public DataSource dynamicDataSource() {
        Map<Object, Object> dataSourceMap = new HashMap<>(2);
        dataSourceMap.put("master1", master1DataSource());
        dataSourceMap.put("master2", master2DataSource());
        //设置动态数据源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        dynamicDataSource.setDefaultTargetDataSource(master1DataSource());
        return dynamicDataSource;
    }
}

3.然后设置一下动态数据源

DynamicDataSource

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

/**
 * 动态数据源
 */
public class DynamicDataSource extends AbstractRoutingDataSource {


    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getContextKey();
    }
}

4.获取数据源

DynamicDataSourceContextHolder

public class DynamicDataSourceContextHolder {

    /**
     * 动态数据源名称上下文
     */
    private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();

    /**
     * 设置数据源
     * @param key
     */
    public static void setContextKey(String key){
        System.out.println("切换数据源"+key);
        DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
    }

    /**
     * 获取数据源名称
     * @return
     */
    public static String getContextKey(){
        String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
        return key == null?"master1":key;
    }

    /**
     * 删除当前数据源名称
     */
    public static void removeContextKey(){
        DATASOURCE_CONTEXT_KEY_HOLDER.remove();
    }
}

5.定义多数据源的切面类

DynamicDataSourceAspect

@Aspect
@Component
public class DynamicDataSourceAspect {

    @Pointcut("@annotation(cn.tisson.yq.enterprise.aspect.DS)")
    public void dataSourcePointCut(){

    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String dsKey = getDSAnnotation(joinPoint).value();
        DynamicDataSourceContextHolder.setContextKey(dsKey);
        try{
            return joinPoint.proceed();
        }finally {
            DynamicDataSourceContextHolder.removeContextKey();
        }
    }

    /**
     * 根据类或方法获取数据源注解
     * @param joinPoint
     * @return
     */
    private DS getDSAnnotation(ProceedingJoinPoint joinPoint){
        Class<?> targetClass = joinPoint.getTarget().getClass();
        DS dsAnnotation = targetClass.getAnnotation(DS.class);
        // 先判断类的注解,再判断方法注解
        if(Objects.nonNull(dsAnnotation)){
            return dsAnnotation;
        }else{
            MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
            return methodSignature.getMethod().getAnnotation(DS.class);
        }
    }
}

6.最后定义一个注解就可以使用了

这里用DS名称,DataSource嘛,自己喜欢

/**
 * 自定义数据源注解
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {

    /**
     * 默认数据源名称
     * @return
     */
    String value() default "master1";

使用

不指定数据源的话默认是使用master1的数据源的,使用数据源的话如:


    @DS("master2") //数据源2
    @Override
    public AppQyJbxxVo findOne(String uniscId) {
        return appQyJbxxMapper.findByUniscId(uniscId);
    }

好的这就解决了,也是参考回来的,方便存储用作学习

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值