Spring Boot配置多数据源(注解方式)

2021/4/29 10:56:28

本文主要是介绍Spring Boot配置多数据源(注解方式),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

看了有些多数据源的整合文章,感觉有点乱,所以自己记录一下以后总会用得到。
别问问什么投原创,我找的几个例子页面找不到了!!!真的!!!
鞠躬了!

SpringBoot多数据源配置(注解方式)

    • Maven依赖
    • yml文件配置
    • 设置数据源常量
    • 功能快捷键
    • 自定义注解
    • 增加配置
    • 增加切面,拦截注解
    • 使用方法

Maven依赖

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

yml文件配置

spring:
  datasource:
    db1:  #实操以及展示
      driver-class-name-: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.1.11:3306/js1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: w123!!
    db2:  #机考
      driver-class-name: com.ibm.db2.jcc.DB2Driver
      jdbc-url: jdbc:db2://192.168.1.134:50000/w
      username: db2admin
      password: "db2admin"

设置数据源常量

这部分是借鉴的!!!(抄的)

public class DataSourceConstants {
	
    public final static String MASTER = "db1";

    public final static String SLAVE = "db2";
}

功能快捷键

这部分是也借鉴的!!!(也是抄的)

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

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getContextKey();
    }
}

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

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

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

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

自定义注解

@Target({ElementType.METHOD,ElementType.TYPE}) 可应用于方法、类、接口

import com.windmill.datasource.DataSourceConstants;

import java.lang.annotation.*;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
	//默认主数据源
    String value() default DataSourceConstants.MASTER;
}

增加配置

@Configuration 定义配置类
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class }) 自定义数据源,不使用SpringBoot默认配置
@Primary 默认优先选择
@ConfigurationProperties 设置默认的属性值
@Bean 将实例注入到Spring IOC

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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 javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
public class DynamicDataSourceConfig {

    @Bean(DataSourceConstants.MASTER)
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(DataSourceConstants.SLAVE)
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DataSource dynamicDataSource() {
        Map<Object, Object> dataSourceMap = new HashMap<>(2);
        dataSourceMap.put(DataSourceConstants.MASTER, masterDataSource());
        dataSourceMap.put(DataSourceConstants.SLAVE, slaveDataSource());
        //设置动态数据源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
        return dynamicDataSource;
    }
}

增加切面,拦截注解

不解释了 :-)

import com.windmill.annotations.DataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Aspect
@Component
public class DynamicDataSourceAspect {
    //拦截注解方法
    @Pointcut("@annotation(com.windmill.annotations.DataSource)")
    public void dataSourcePointCut() {
    }

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

    /**
     * 根据类或方法获取数据源注解
     */
    private DataSource getDSAnnotation(ProceedingJoinPoint joinPoint) {
        //mybatis生成的代理类,所以获取它的接口来获取DbAnnotation注解信息
        Class<?> targetClass = joinPoint.getTarget().getClass().getInterfaces()[0];
        DataSource dsAnnotation = targetClass.getAnnotation(DataSource.class);
        // 先判断类的注解,再判断方法注解
        if (Objects.nonNull(dsAnnotation)) {
            return dsAnnotation;
        } else {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            DataSource annotation = methodSignature.getMethod().getAnnotation(DataSource.class);
            return annotation;
        }
    }
}

使用方法

@Mapper
public interface BaseInfoMapper {
    @DataSource(DataSourceConstants.SLAVE)
    List<Baseinfo> selectUserList(@Param("orgId") orgId);
}


这篇关于Spring Boot配置多数据源(注解方式)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程