springboot 集成 druid ,多数据源

1.config配置类

/**
*
*注解类,后面用来标注DAO方法
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.TYPE})
public @interface DS {
    String value();
}

/**
 * 
 * 简单的路由规则,用来设置当前数据库连接
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        Object key;
        if (DynamicDataSourceHolder.isMaster()) {
            key = DynamicDataSourceHolder.MASTER;
        } else if (DynamicDataSourceHolder.isForm()) {
            key = DynamicDataSourceHolder.FORM;
        } else {
            key = DynamicDataSourceHolder.MASTER;
        }
        return key;
    }

    @Override
    public void afterPropertiesSet() {
        super.afterPropertiesSet();
    }
}
/**
 * 配置类,用来读取yml文件中数据库配置
 * 
 */
@ConfigurationProperties(prefix = "dynamic")
public class DynamicDataSourceConfig {
	
	private Map<String,DruidDataSource> datasources = new HashMap<>();
	
	public Map<String,DruidDataSource> getDatasources() {
		return datasources;
	}

	public void setDatasources(Map<String,DruidDataSource> datasources) {
		this.datasources = datasources;
	}
}
/**
 * 动态数据源配置类,用来加载配置的数据源
 */
@Configuration
@EnableConfigurationProperties(DynamicDataSourceConfig.class)
public class DynamicDataSourceConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSourceConfiguration.class);

    private final DynamicDataSourceConfig dynamicDataSourceConfig;

    public DynamicDataSourceConfiguration(DynamicDataSourceConfig dynamicDataSourceConfig) {
        this.dynamicDataSourceConfig = dynamicDataSourceConfig;
    }

    @Bean
    public DynamicDataSource dynamicDataSource() throws SQLException {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();

        Map<Object, Object> dataSources = new HashMap<>(2);

        for (Map.Entry<String, DruidDataSource> entry : dynamicDataSourceConfig.getDatasources().entrySet()) {
            String key = entry.getKey();
            DruidDataSource dataSource = entry.getValue();
            if (!key.equals(DynamicDataSourceHolder.MASTER)) {
                dataSources.put(key, dataSource);
            }
            dataSource.init();
            LOGGER.info("init dataSource:{}", key);
        }

        DruidDataSource masterDataSource = dynamicDataSourceConfig.getDatasources().get(DynamicDataSourceHolder.MASTER);

        if (masterDataSource == null) {
            throw new IllegalArgumentException("Undefined master database");
        }

        dataSources.put(DynamicDataSourceHolder.MASTER, masterDataSource);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
        dynamicDataSource.setTargetDataSources(dataSources);

        return dynamicDataSource;
    }
}
/**
 * 配合注解使用,用来标记DAO方法
 */
public class DynamicDataSourceHolder {

    public static final String MASTER = "master";

    public static final String SLAVE = "slave";

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

    private static void putDataSourceKey(String key) {
        HOLDER.set(key);
    }

    public static String getDataSourceKey() {
        return HOLDER.get();
    }

    public static void markMaster() {
        putDataSourceKey(MASTER);
    }

    public static void markSLAVE() {
        putDataSourceKey(SLAVE);
    }

    public static boolean isMaster() {
        return MASTER.equals(HOLDER.get());
    }

    public static boolean isSlave() {
        return SLAVE.equals(HOLDER.get());
    }
}
/**
 * 切面类,通过@DS注解动态给DAO方法注入指定的数据源
 */
@Order(-1)
@Aspect
@Component
public class DynamicDatasourceAop {

    @Pointcut(value = "execution(* io.nonda.zus.common.repository.dao.mybatis.pgsql.*.*(..))")
    public void dao() {
    }

    @Before("dao()")
    public void beforeService(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        DS ds = method.getAnnotation(DS.class);
        if (null == ds) {
            DynamicDataSourceHolder.markMaster();
        } else if (DynamicDataSourceHolder.FORM.equals(ds.value())) {
            DynamicDataSourceHolder.markFORM();
        } else {
            DynamicDataSourceHolder.markMaster();
        }
    }
}

2.yml配置: 如果是mysql,只需要修改driver-class-name驱动类即可

dynamic:
  datasources:
    master:
      url: jdbc:postgresql://nonxxxt-1.rds.xxx.com:5432/test
      username: xx
      password: xxx
      driver-class-name: org.postgresql.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      druid:
        initial-size: 1
        min-idle: 5
        max-active: 5
        max-wait: 60000
        time-between-eviction-runs-millisr: 28000
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 'x'
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: false
        max-pool-prepared-statement-per-connection-size: 20
        filters: stat,wall,slf4j
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
        use-global-data-source-stat: true
        remove-abandoned: true
        print-sql: false
    slave:
      url: jdbc:postgresql://xx-x-qa.xxx.us-east-1.rds.amazonaws.com:5432/test
      username: xx
      password: xxx
      driver-class-name: org.postgresql.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      druid:
        initial-size: 1
        min-idle: 5
        max-active: 5
        max-wait: 60000
        time-between-eviction-runs-millisr: 28000
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 'x'
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: false
        max-pool-prepared-statement-per-connection-size: 20
        filters: stat,wall,slf4j
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
        use-global-data-source-stat: true
        remove-abandoned: true
        print-sql: false

3.使用方式

public interface IObdCodeInfoDAO {
    // aop动态解析的时候,设置了不指定默认为master数据源
    int deleteByPrimaryKey(String id);
    // 指定master数据源
    @DS(DynamicDataSourceHolder.MASTER)
    int insert(ObdCodeInfoPO record);
    // 指定slave数据源
    @DS(DynamicDataSourceHolder.SLAVE)
    int insertSelective(ObdCodeInfoPO record);

}

通过上面的配置,即可简单的完成多数据源的配置和使用,如果需要增加数据源,在以上代码上扩展即可。

MARK:

最近在关注一个手机挖矿项目,叫Bee蜜蜂币。

APP 下载链接: https://bee.com/sc/

推荐码:lei911gang

手机免费挖矿,感兴趣的可以一起加入。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值