使用springboot + druid + mybatisplus完成多数据源配置

最近项目中需要使用多个数据源完成业务,经过多方寻找资料和亲自测试,现在整理一下资料。本文参考:https://www.cnblogs.com/hsbt2333/p/9347249.html

1.在yml中配置多个数据源访问连接

server:
  port: 8099
#配置数据源的属性
spring:
  datasource:
    druid:
      db1:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/standarddb?useUnicode=true&characterEncoding=utf8&nullCatalogMeansCurrent=true&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: ********
      db2:
        url: jdbc:mysql://IP:3306/rebiaoserver?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
        username: root
        password: ********
        driver-class-name: com.mysql.cj.jdbc.Driver
   #监控配置
      stat-view-servlet:
        enabled: true
        login-username: root
        login-password: roo
  #thymeleaf的配置 
  thymeleaf: 
    cache: false
    enabled: true
   #设置开发环境
  profiles:
    active: dev
  #时区转换
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  #redis
  redis:
    database: 0
    host: 127.0.0.1
    #password: 123
    port: 6379
    timeout: 3000       # 连接超时时间 单位 ms(毫秒)
    #    cluster:
    #     nodes: 10.3.1.4:7000,10.3.1.4:7001,...,10.3.1.4:7008

#配置mybatisplus
mybatis-plus:
  mapper-locations:
  - classpath:mapper/*/*Mapper.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0
    banner: true
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 分页插件
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql

2. 建立数据源枚举类DataSourceEnum

package com.ckfuture.pro.DBSource;
/**
 * @description: 多数据源枚举
 * @author: CKFuture
 * @since: 2021-11-09 13:33
 * @version: v1.0
 * @LastEditTime:
 * @LastEditors:
 * @copyright: hrbckfuture.com
 */
public enum DataSourceEnum {
    DB1("db1"),DB2("db2");

    private String value;

    DataSourceEnum(String value){this.value=value;}

    public String getValue() {
        return value;
    }
}

3. 建立DataSourceContextHolder类

package com.ckfuture.pro.DBSource;


public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new InheritableThreadLocal<>();

    /**
     *  设置数据源
     * @param db
     */
    public static void setDataSource(String db){
        contextHolder.set(db);
    }

    /**
     * 取得当前数据源
     * @return
     */
    public static String getDataSource(){
        return contextHolder.get();
    }

    /**
     * 清除上下文数据
     */
    public static void clear(){
        contextHolder.remove();
    }
}

4. 建立MultipleDataSource类

package com.ckfuture.pro.DBSource;

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

public class MultipleDataSource extends AbstractRoutingDataSource {

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

5.建立DataSource注解

package com.ckfuture.pro.annotation;


import com.ckfuture.pro.DBSource.DataSourceEnum;

import java.lang.annotation.*;
/**
 * @description: DataSource注解
 * @author: CKFuture
 * @since: 2021-11-09 13:35
 * @version: v1.0
 * @LastEditTime:
 * @LastEditors:
 * @copyright: hrbckfuture.com
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {

    DataSourceEnum value() default DataSourceEnum.DB1;
}

 

 6.建立DataSourceAspect类

package com.ckfuture.pro.DBSource;

import com.ckfuture.pro.annotation.DataSource;
import lombok.extern.slf4j.Slf4j;
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;


@Component
@Slf4j
@Aspect
@Order(-1)
public class DataSourceAspect {

    @Pointcut("@within(com.ckfuture.pro.annotation.DataSource) || @annotation(com.ckfuture.pro.annotation.DataSource)")
    public void pointCut(){

    }

    @Before("pointCut() && @annotation(dataSource)")
    public void doBefore(DataSource dataSource){
        log.info("选择数据源---"+dataSource.value().getValue());
        DataSourceContextHolder.setDataSource(dataSource.value().getValue());
    }

    @After("pointCut()")
    public void doAfter(){
        DataSourceContextHolder.clear();
    }
}

7.建立配置类MyBatiesPlusConfiguration

package com.ckfuture.pro.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
/*import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;*/

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.ckfuture.pro.DBSource.DataSourceEnum;
import com.ckfuture.pro.DBSource.MultipleDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
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 org.springframework.context.annotation.Profile;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@MapperScan("com.ckfuture.pro.*.*.dao")
public class MyBatiesPlusConfiguration {


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

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

    /**
     * 动态数据源配置
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
        MultipleDataSource multipleDataSource = new MultipleDataSource();
        Map< Object, Object > targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceEnum.DB1.getValue(), db1);
        targetDataSources.put(DataSourceEnum.DB2.getValue(), db2);
        //添加数据源
        multipleDataSource.setTargetDataSources(targetDataSources);
        //设置默认数据源
        multipleDataSource.setDefaultTargetDataSource(db1);
        return multipleDataSource;
    }
}

8.使用数据源1

只需要在服务实现类的方法上添加注解@DataSource(DataSourceEnum.DB1)即可。

 

 9.使用数据源2

只需要在服务实现类的方法上添加注解@DataSource(DataSourceEnum.DB2)即可。

 

 这里本人抛砖引玉,个人建议还是尽量不要在springboot中使用多数据源,第一是比较麻烦,第二是不安全,还是建议使用springcloud。

 
posted @ 2021-11-09 13:55  创客未来  阅读(757)  评论(1编辑  收藏  举报