Springboot配置多数据源

【在使用前需要搭建好一个springboot+plus的项目,之后全程复制即可】

yml

server:
  port: 9001
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      master:
        url: jdbc:mysql://127.0.0.1:3306/seata_order?useUnicode=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=false
        username: root
        password: root
      slave:
        url: jdbc:mysql://127.0.0.1:3306/lianxi?useUnicode=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=false
        username: root
        password: root
      initialSize: 5
      # 最小连接池数量
      minIdle: 10
      # 最大连接池数量
      maxActive: 20
      # 配置获取连接等待超时的时间
      maxWait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      # 配置一个连接在池中最大生存的时间,单位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # 配置检测连接是否有效
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # 设置白名单,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # 控制台管理用户名和密码
        login-username:
        login-password:
      filter:
        stat:
          enabled: true
          # 慢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true

POM文件

    <!-- 添加父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.projectlombok.version>1.18.20</org.projectlombok.version>
    </properties>


    <dependencies>
        <!-- 热部署配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <!-- 加入web开发的支持  集成servlet 和tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- 加入mysql的驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version> 8.0.27</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        
        <!--控制日志信息输送的目的地是控制台、文件、GUI组件-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>


        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <scope>provided</scope> <!-- 设置为 provided,主要是 ErrorCodeProperties 使用到 -->
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->
        </dependency>
        
        <!-- yml设置MySQL数据源的type为:com.alibaba.druid.pool.DruidDataSource的时候需要添加这个依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.11</version>
        </dependency>
        
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
            <scope>provided</scope>
            <!--<optional>true</optional>-->
        </dependency>

        <!--类转换配置 convert -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>

        <!--糊涂工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.9</version>
        </dependency>


        <!-- alibaba easyexcel依赖 开始-->
        <!--读取Excel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.jeecg</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- alibaba easyexcel依赖 结束-->


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${org.projectlombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

枚举

@Getter
public enum DataSourceEnum {

    MASTER("master","MASTER"),SLAVE("slave","SLAVE");

    private final String name;

    private final String code;

    DataSourceEnum(String name, String code) {
        this.name = name;
        this.code = code;
    }
}

数据源注解

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MasterSlave {

    DataSourceEnum value();
}

ThreadLocal工具类

@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {

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

    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return getDataSource();
    }

    /**
     * 清除数据源
     */
    public static void clearDataSource() {
        log.info("删除数据源:{}", CONTEXT_HOLDER.get());
        CONTEXT_HOLDER.remove();
    }

    /**
     * 设置数据源
     *
     * @param dsType master/slaver
     */
    public static void setDataSource(String dsType) {
        log.info("切换到:{}数据源", dsType);
        CONTEXT_HOLDER.set(dsType);
    }

    /**
     * 获取数据源
     */
    public static String getDataSource() {
        return CONTEXT_HOLDER.get();
    }

}

数据源Bean

@Configuration
@Slf4j
public class DynamicDataSourceConfig {

    @Bean
    @Primary
    public DynamicDataSource dataSource() {
        Map<Object, Object> targetDataSources = new HashMap<>(5);
        targetDataSources.put(DataSourceEnum.MASTER.getCode(), this.masterDataSource());
        targetDataSources.put(DataSourceEnum.SLAVE.getCode(), this.slaveDataSource());
        return new DynamicDataSource(this.masterDataSource(), targetDataSources);
    }

    @Bean(name = "masterDataSource")
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "slaveDataSource")
    @ConfigurationProperties("spring.datasource.druid.slave")
    public DataSource slaveDataSource() {
        return DruidDataSourceBuilder.create().build();
    }
    
}

AOP切面

@Component
@Aspect
@Slf4j
public class DynamicDataSourceAspect {

    @Around("@annotation(masterSlave)")
    public Object around(ProceedingJoinPoint joinPoint, MasterSlave masterSlave) throws Throwable {
        MasterSlave dataSource = this.getDataSource(joinPoint);
        if (!Objects.isNull(dataSource)) {
            DynamicDataSource.setDataSource(dataSource.value().getCode());
        }
        Object var3;
        try {
            var3 = joinPoint.proceed();
        } finally {
            DynamicDataSource.clearDataSource();
        }
        return var3;
    }


    public MasterSlave getDataSource(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        return method.getAnnotation(MasterSlave.class);
    }
}

启动类

@Slf4j
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@Import({DynamicDataSourceConfig.class})
@MapperScan("com.boot.mapper")

public class ZStartBoot {
    public static void main(String[] args) {
        SpringApplication.run(ZStartBoot.class, args);
        log.info("项目服务器启动了");
    }
}

使用

	@PostMapping("/MASTER")
    @MasterSlave(value = DataSourceEnum.MASTER)
    public User MASTER(@RequestBody @Valid User u) {
        return userService.getById(u.getId());
    }

    @PostMapping("/SLAVE")
    @MasterSlave(value = DataSourceEnum.SLAVE)
    public User SLAVE(@RequestBody @Valid User u) {
        return userService.getById(u.getId());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值