Springboot 多数据源 dynamic-datasource动态添加移除数据源

这篇具有很好参考价值的文章主要介绍了Springboot 多数据源 dynamic-datasource动态添加移除数据源。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0.前言

上一篇文章我们讲了如何通过多数据源组件,在Spring boot Druid 连接池项目中配置多数据源,并且通过@DS注解的方式切换数据源,《Spring Boot 配置多数据源【最简单的方式】》。但是在多租户的业务场景中,我们通常需要手动的切换数据源,那么本文将解答你的额疑惑。

1. 动态添加移除数据源

dynamic-datasource是一款基于Spring Boot 动态数据源框架,在应用程序运行时可以动态添加、移除数据源的功能。
Springboot 多数据源 dynamic-datasource动态添加移除数据源,Mybatis-Plus进阶系列,后端,java,spring boot

2.基础介绍

本文我们还是以dynamic-datasource来进阶学习。提供了一系列的API和配置项,可以非常方便地实现动态添加、移除数据源的功能。本文将介绍如何使用dynamic-datasource动态添加、移除数据源,并对相关代码进行解析。在多租户应用、读写分离等场景下,动态数据源可以方便地实现数据源的动态切换,提高应用程序的灵活性和扩展性。
主要在多租户场景中,常常新的一个租户进来需要动态的添加一个数据源到库中,使得系统不用重启即可切换数据源。

3. 使用步骤示例

dynamic-datasource 3.4.0及以上版本和老版本注入方式有一定差别,根据自己版本注入。
注意一定要让多数据源使用 @Primary ,让其成为主数据源。

简单示例,自己手动构造dataSource

//3.4.0版本以下
@Primary
@Bean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) { 
    DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
    dataSource.setPrimary(properties.getPrimary());
    dataSource.setStrict(properties.getStrict());
    dataSource.setStrategy(properties.getStrategy());
    dataSource.setProvider(dynamicDataSourceProvider);
    dataSource.setP6spy(properties.getP6spy());
    dataSource.setSeata(properties.getSeata());
    return dataSource;
}

//3.4.0版本及以上
@Primary
@Bean
public DataSource dataSource() {
    DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
    dataSource.setPrimary(properties.getPrimary());
    dataSource.setStrict(properties.getStrict());
    dataSource.setStrategy(properties.getStrategy());
    dataSource.setP6spy(properties.getP6spy());
    dataSource.setSeata(properties.getSeata());
    return dataSource;
}

主要变更是因为3.4.0支持了多个provider同时生效,采取了内部注入。 源码改动参考
https://github.com/baomidou/dynamic-datasource-spring-boot-starter/commit/6e8d2954499f83269302d23b58f8832c31e07ef7

复杂示例,使用DataSourceCreator构造dataSource

本文我们还是以dynamic-datasource来进阶学习。提供了一系列的API和配置项,可以非常方便地实现动态添加、移除数据源的功能。本文将介绍如何使用dynamic-datasource动态添加、移除数据源,并对相关代码进行解析。在多租户应用、读写分离等场景下,动态数据源可以方便地实现数据源的动态切换,提高应用程序的灵活性和扩展性。
主要在多租户场景中,常常新的一个租户进来需要动态的添加一个数据源到库中,使得系统不用重启即可切换数据源。

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.*;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.samples.ds.dto.DataSourceDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import java.util.Set;

@RestController
@RequestMapping("/datasources")
@Api(tags = "添加删除数据源")
public class DataSourceController {

    @Autowired
    private DataSource dataSource;
   // private final DataSourceCreator dataSourceCreator; //3.3.1及以下版本使用这个通用,强烈推荐sb2用户至少升级到3.5.2版本

    @Autowired
    private DefaultDataSourceCreator dataSourceCreator;
//如果是用4.x以上版本,因为要和spring解绑,重构了一些东西,比如缺少了懒启动和启动初始化数据库。不太建议用以下独立的创建器,只建议用上面的DefaultDataSourceCreator 
    @Autowired
    private BasicDataSourceCreator basicDataSourceCreator;
    @Autowired
    private JndiDataSourceCreator jndiDataSourceCreator;
    @Autowired
    private DruidDataSourceCreator druidDataSourceCreator;
    @Autowired
    private HikariDataSourceCreator hikariDataSourceCreator;
    @Autowired
    private BeeCpDataSourceCreator beeCpDataSourceCreator;
    @Autowired
    private Dbcp2DataSourceCreator dbcp2DataSourceCreator;

    @GetMapping
    @ApiOperation("获取当前所有数据源")
    public Set<String> now() {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        return ds.getDataSources().keySet();
    }

    //通用数据源会根据maven中配置的连接池根据顺序依次选择。
    //默认的顺序为druid>hikaricp>beecp>dbcp>spring basic
    @PostMapping("/add")
    @ApiOperation("通用添加数据源(推荐)")
    public Set<String> add(@Validated @RequestBody DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(dto, dataSourceProperty);
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
        ds.addDataSource(dto.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    @PostMapping("/addBasic(强烈不推荐,除了用了马上移除)")
    @ApiOperation(value = "添加基础数据源", notes = "调用Springboot内置方法创建数据源,兼容1,2")
    public Set<String> addBasic(@Validated @RequestBody DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(dto, dataSourceProperty);
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = basicDataSourceCreator.createDataSource(dataSourceProperty);
        ds.addDataSource(dto.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    @PostMapping("/addJndi")
    @ApiOperation("添加JNDI数据源")
    public Set<String> addJndi(String pollName, String jndiName) {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = jndiDataSourceCreator.createDataSource(jndiName);
        ds.addDataSource(poolName, dataSource);
        return ds.getDataSources().keySet();
    }

    @PostMapping("/addDruid")
    @ApiOperation("基础Druid数据源")
    public Set<String> addDruid(@Validated @RequestBody DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(dto, dataSourceProperty);
        dataSourceProperty.setLazy(true);
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = druidDataSourceCreator.createDataSource(dataSourceProperty);
        ds.addDataSource(dto.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    @PostMapping("/addHikariCP")
    @ApiOperation("基础HikariCP数据源")
    public Set<String> addHikariCP(@Validated @RequestBody DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(dto, dataSourceProperty);
        dataSourceProperty.setLazy(true);//3.4.0版本以下如果有此属性,需手动设置,不然会空指针。
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = hikariDataSourceCreator.createDataSource(dataSourceProperty);
        ds.addDataSource(dto.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    @PostMapping("/addBeeCp")
    @ApiOperation("基础BeeCp数据源")
    public Set<String> addBeeCp(@Validated @RequestBody DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(dto, dataSourceProperty);
        dataSourceProperty.setLazy(true);//3.4.0版本以下如果有此属性,需手动设置,不然会空指针。
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = beeCpDataSourceCreator.createDataSource(dataSourceProperty);
        ds.addDataSource(dto.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    @PostMapping("/addDbcp")
    @ApiOperation("基础Dbcp数据源")
    public Set<String> addDbcp(@Validated @RequestBody DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(dto, dataSourceProperty);
        dataSourceProperty.setLazy(true);//3.4.0版本以下如果有此属性,需手动设置,不然会空指针。
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = dbcp2DataSourceCreator.createDataSource(dataSourceProperty);
        ds.addDataSource(dto.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    @DeleteMapping
    @ApiOperation("删除数据源")
    public String remove(String name) {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        ds.removeDataSource(name);
        return "删除成功";
    }
}

4. 示例项目

https://github.com/dynamic-datasource/dynamic-datasource-samples/tree/master/features-samples/add-remove-datasource-sample

5. 源码分析

public interface DataSourceCreator {

    /**
     * 通过属性创建数据源
     *
     * @param dataSourceProperty 数据源属性
     * @return 被创建的数据源
     */
    DataSource createDataSource(DataSourceProperty dataSourceProperty);

    /**
     * 当前创建器是否支持根据此属性创建
     *
     * @param dataSourceProperty 数据源属性
     * @return 是否支持
     */
    boolean support(DataSourceProperty dataSourceProperty);
}

DataSourceCreator是一个接口,定义了根据参数创建数据源的接口。
其他creator实现此接口,本项目暂时实现了Druid和Hikaricp的等连接池的实现。
BasicDataSourceCreator 是调用Spring原生的创建方式,只支持最最原始的基础配置。
DefaultDataSourceCreator 是一个通用的创建器,其根据环境自动选择连接池,文章来源地址https://www.toymoban.com/news/detail-647852.html

到了这里,关于Springboot 多数据源 dynamic-datasource动态添加移除数据源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Springboot+mybatis-plus+dynamic-datasource+Druid 多数据源 分布式事务

    背景 处理多数据源事务一直是一个复杂而棘手的问题,通常我们有两种主流的解决方法。 第一种是通过Atomikos手动创建多数据源事务,这种方法更适合数据源数量较少,参数配置不复杂,对性能要求不高的项目。然而,这种方法的最大困难在于需要手动配置大量设置,这可能

    2024年02月11日
    浏览(36)
  • 【源码解析】多数据源 dynamic-datasource快速入门及源码解析

    启动的时候,会加载在 dynamic-datasource-spring-boot-starter 的jar包中的 spring.factories 在 DynamicDataSourceAutoConfiguration 会注入 DynamicRoutingDataSource DynamicRoutingDataSource#afterPropertiesSet ,系统启动的时候会加载所有的数据源 在 DynamicDataSourceAutoConfiguration 会注入 DynamicDataSourceProvider AbstractData

    2023年04月21日
    浏览(56)
  • Dynamic DataSource 多数据源配置【 Springboot + DataSource + MyBatis Plus + Druid】

    MybatisPlus多数据源配置主要解决的是多数据库连接和切换的问题。在一些大型应用中,由于数据量的增长或者业务模块的增多,可能需要访问多个数据库。这时,就需要配置多个数据源。 2.1.1、引用依赖 2.1.2、application.yml 配置 2.1.3、通用配置类 2.1.4、使用方式 这里便不过多的

    2024年02月03日
    浏览(45)
  • Springboot+dynamic-datasource+Druid数据库配置加密

    Springboot+mybatis-plus+dynamic-datasource+Druid数据库配置加密 背景 生产环境中, 为了保密,我们希望将数据库密码加密, 甚至用户名和jdbc连接串加密。本章我们使用由苞米豆(baomidou)团队开发的 dynamic-datasource 多数据源组件自带的加密工具实现数据库配置加密 从 dynamic-datasource-star

    2024年02月04日
    浏览(41)
  • 使用多数据源dynamic-datasource-spring-boot-starter遇到的问题记录

    记录使用多数据源dynamic-datasource-spring-boot-starter遇到的问题: 1、工程启动失败 缺少clickhouse连接驱动,引入对应的maven依赖 2、clickhouse的sql语句读到了mysql数据库 在工程的配置文件只配置了ck数据源配置的时候,@DS(“数据源名称”)用在service接口上没什么问题。 由于新的需求

    2024年02月15日
    浏览(54)
  • 使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库

    记录 :415 场景 :使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库。 版本 :JDK 1.8,Spring Boot 2.6.3,dynamic-datasource-spring-boot-starter-3.3.2,mybatis-3.5.9。 源码 :https://github.com/baomidou/dynamic-datasource-spring-boot-starter dynamic-datasource-spring-boot-starter :一个基于springboot的快

    2023年04月19日
    浏览(44)
  • 分享一个优秀的动态数据源开源库-dynamic-datasource-spring-boot-starter

    在我们的Java后端研发工作中, 有时候由于业务的快速迭代和数据的安全隔离性,往往会为不同的 API业务线分配不同的数据库,即一个微服务经常需要和多个数据源打交道。 dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。 其支持 Jdk 1.7+, Spring

    2024年02月12日
    浏览(56)
  • 苞米豆的多数据源 → dynamic-datasource-spring-boot-starter,挺香的!

    2023年元旦,我妈又开始了对我的念叨 妈:你到底想多少岁结婚 我:60 妈:60,你想找个多大的 我:找个55的啊,她55我60,结婚都有退休金,不用上班不用生孩子,不用买车买房,成天就是玩儿 我:而且一结婚就是白头偕老,多好 我妈直接一大嘴巴子呼我脸上 最近接到一个

    2023年04月21日
    浏览(40)
  • 使用dynamic-datasource-spring-boot-starter动态切换数据源操作数据库(MyBatis-3.5.9)

    记录 :383 场景 :使用dynamic-datasource-spring-boot-starter动态切换数据源,使用MyBatis操作数据库。提供三种示例:一,使用@DS注解作用到类上。二,使用@DS注解作用到方法上。三,不使用注解,使用DynamicDataSourceContextHolder类在方法内灵活切换不同数据源。 源码: https://github.com/

    2024年01月20日
    浏览(51)
  • MyBatis Plus 插件 动态数据源实现原理与源码讲解 (dynamic-datasource-spring-boot-starter-master)

    目录 1. 介绍 2. 基本原理 3. 源码介绍 3.1 使用 AOP 拦截,方法执行前获取到当前方法要用的数据源 3.2 实现自定义 DataSource 接口,实现 DataSource 接口的 getConnect 方法做动态处理 多数据源即一个项目中同时存在多个不同的数据库连接池。 比如 127.0.0.1:3306/test   127.0.0.1:3307/test 

    2024年02月07日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包