当前位置: 首页 > news >正文

黑龙江做网站南昌网站开发公司

黑龙江做网站,南昌网站开发公司,厦门在建工程项目,WordPress交互式网站【Spring】DynamicDataSourceHolder 动态数据源切换 常见场景常见工具一、AbstractRoutingDataSource1.1、 定义 DynamicDataSourceHolder1.2、 配置动态数据源1.3、 在Spring配置中定义数据源1.4、在业务代码中切换数据源 二、Dynamic Datasource for Spring Boot2.1. 添加依赖…

【Spring】DynamicDataSourceHolder 动态数据源切换

    • 常见场景
    • 常见工具
    • 一、AbstractRoutingDataSource
      • 1.1、 定义 DynamicDataSourceHolder
      • 1.2、 配置动态数据源
      • 1.3、 在Spring配置中定义数据源
      • 1.4、在业务代码中切换数据源
    • 二、Dynamic Datasource for Spring Boot
      • 2.1. 添加依赖
      • 2.2. 配置数据源
    • 2.3. 使用注解切换数据源
      • 2.4. 启动类配置
    • 三、阿里巴巴的Druid
      • 3.1. 引入依赖
      • 3.2. 配置多数据源
      • 3.3. 实现动态数据源路由
      • 3.4. 创建数据源上下文持有者
      • 3.5. 配置数据源
      • 3.6. 使用动态数据源

一个开发系统需要用多个数据库怎么办呢?可不可以连接多个数据库?
当然可以!随意切换。
DynamicDataSourceHolder 通常是用于动态数据源切换的一个工具类,特别是在多数据源场景下使用。它通过 ThreadLocal 来保存当前线程的数据源标识,以便在同一线程中能够动态切换不同的数据源。

常见场景

在实际项目中,可能需要根据不同的业务需求在多个数据源之间进行切换。比如,读写分离(主从库)、多租户架构等。通过DynamicDataSourceHolder可以方便地实现这一需求。

常见工具

有许多现有的动态数据源管理工具和框架,可以帮助简化多数据源配置和管理。以下是一些常用的工具和框架:

  1. Spring Boot DataSource Routing with AbstractRoutingDataSource
    Spring本身提供了 AbstractRoutingDataSource 类,可以用于实现动态数据源路由。

  2. Spring Cloud DataSource Routing
    在Spring Cloud环境中,可以使用Spring Cloud提供的配置和工具实现动态数据源管理。

  3. MyBatis Dynamic Datasource
    MyBatis提供了一个动态数据源插件mybatis-spring,可以用于在MyBatis中实现动态数据源切换。

  4. Dynamic Datasource for Spring Boot
    动态数据源管理库 dynamic-datasource-spring-boot-starter,是一个简单易用的Spring Boot动态数据源启动器,支持多种数据源配置和切换。

  5. Druid Dynamic Datasource
    阿里巴巴的Druid数据源也支持动态数据源切换,可以通过配置Druid的相关属性实现。

下面详细介绍一下 Spring本身提供的 AbstractRoutingDataSource 、SpringBoot 动态数据启动器、以及现在常用的阿里巴巴的Druid数据源。

一、AbstractRoutingDataSource

1.1、 定义 DynamicDataSourceHolder

public class DynamicDataSourceHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();/*** 设置数据源* @param dataSourceKey 数据源标识*/public static void setDataSource(String dataSourceKey) {contextHolder.set(dataSourceKey);}/*** 获取数据源* @return 数据源标识*/public static String getDataSource() {return contextHolder.get();}/*** 清除数据源*/public static void clearDataSource() {contextHolder.remove();}
}

1.2、 配置动态数据源

需要配置一个 AbstractRoutingDataSource 来实现动态数据源的路由。

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicRoutingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceHolder.getDataSource();}
}

1.3、 在Spring配置中定义数据源

在Spring配置中定义数据源,并将动态数据源配置为主数据源。

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.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Configuration
public class DataSourceConfig {@Bean(name = "dataSource1")@ConfigurationProperties(prefix = "spring.datasource.ds1")public DataSource dataSource1() {return DataSourceBuilder.create().build();}@Bean(name = "dataSource2")@ConfigurationProperties(prefix = "spring.datasource.ds2")public DataSource dataSource2() {return DataSourceBuilder.create().build();}@Primary@Bean(name = "dataSource")public DataSource dataSource(@Qualifier("dataSource1") DataSource dataSource1,@Qualifier("dataSource2") DataSource dataSource2) {DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("ds1", dataSource1);targetDataSources.put("ds2", dataSource2);dynamicRoutingDataSource.setTargetDataSources(targetDataSources);dynamicRoutingDataSource.setDefaultTargetDataSource(dataSource1);return dynamicRoutingDataSource;}
}

1.4、在业务代码中切换数据源

在需要切换数据源的业务逻辑中使用 DynamicDataSourceHolder 来设置当前数据源。

@Service
public class SomeService {@Transactionalpublic void someMethod() {// 切换到数据源 ds1DynamicDataSourceHolder.setDataSource("ds1");// 执行与数据源 ds1 相关的操作// 切换到数据源 ds2DynamicDataSourceHolder.setDataSource("ds2");// 执行与数据源 ds2 相关的操作// 恢复到默认数据源DynamicDataSourceHolder.clearDataSource();}
}

DynamicDataSourceHolder 通过 ThreadLocal 实现了线程级别的数据源切换,结合 AbstractRoutingDataSource 实现动态数据源路由,可以方便地在多数据源场景下进行数据源的动态切换。需要注意的是,在使用动态数据源时,要确保在合适的时机清除线程本地变量,以防止数据源混乱。

二、Dynamic Datasource for Spring Boot

2.1. 添加依赖

在pom.xml中添加dynamic-datasource-spring-boot-starter依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.4.0</version>
</dependency>

2.2. 配置数据源

在application.yml或application.properties中配置多个数据源:

spring:datasource:dynamic:primary: masterdatasource:master:url: jdbc:mysql://localhost:3306/master_dbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://localhost:3306/slave_dbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

2.3. 使用注解切换数据源

使用@DS 注解在需要的方法或类上指定数据源:

import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@DS("slave")@Transactionalpublic void getSlaveData() {// 逻辑使用从库数据源}@DS("master")@Transactionalpublic void getMasterData() {// 逻辑使用主库数据源}
}

2.4. 启动类配置

在Spring Boot启动类中启用动态数据源支持:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

三、阿里巴巴的Druid

阿里巴巴的Druid 是一个高效、稳定且功能强大的数据库连接池,支持监控、日志输出和多种数据库管理功能。Druid也支持动态数据源切换,通过配置Druid的相关属性和使用Spring的AbstractRoutingDataSource来实现。

3.1. 引入依赖

在你的Spring Boot项目中引入Druid依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version>
</dependency>

3.2. 配置多数据源

application.yml 中配置多个数据源。Druid支持的数据源配置属性非常丰富,可以配置连接池大小、超时设置、日志等。

spring:datasource:dynamic:primary: masterdatasource:master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/master_dbusername: rootpassword: rootdruid:initial-size: 5min-idle: 5max-active: 20max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: SELECT 1 FROM DUALtest-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 20filters: stat,wall,log4jslave:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/slave_dbusername: rootpassword: rootdruid:initial-size: 5min-idle: 5max-active: 20max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: SELECT 1 FROM DUALtest-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 20filters: stat,wall,log4j

3.3. 实现动态数据源路由

通过继承Spring的 AbstractRoutingDataSource 实现动态数据源路由逻辑。

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicRoutingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceKey();}
}

3.4. 创建数据源上下文持有者

使用 ThreadLocal 来保存当前线程的数据源标识。

public class DynamicDataSourceContextHolder {private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();public static void setDataSourceKey(String key) {CONTEXT_HOLDER.set(key);}public static String getDataSourceKey() {return CONTEXT_HOLDER.get();}public static void clearDataSourceKey() {CONTEXT_HOLDER.remove();}
}

3.5. 配置数据源

在Spring配置类中配置Druid数据源和动态数据源路由。

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
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.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.dynamic.datasource.master")public DataSource masterDataSource() {return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.dynamic.datasource.slave")public DataSource slaveDataSource() {return DruidDataSourceBuilder.create().build();}@Primary@Beanpublic DataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource,@Qualifier("slaveDataSource") DataSource slaveDataSource) {DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("master", masterDataSource);targetDataSources.put("slave", slaveDataSource);dynamicRoutingDataSource.setTargetDataSources(targetDataSources);dynamicRoutingDataSource.setDefaultTargetDataSource(masterDataSource);return dynamicRoutingDataSource;}
}

3.6. 使用动态数据源

在需要切换数据源的业务逻辑中使用 DynamicDataSourceContextHolder 来设置当前数据源。

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Transactionalpublic void useMaster() {DynamicDataSourceContextHolder.setDataSourceKey("master");// 使用主库执行操作DynamicDataSourceContextHolder.clearDataSourceKey();}@Transactionalpublic void useSlave() {DynamicDataSourceContextHolder.setDataSourceKey("slave");// 使用从库执行操作DynamicDataSourceContextHolder.clearDataSourceKey();}
}

总结
Druid Dynamic Datasource通过结合Spring的AbstractRoutingDataSource和ThreadLocal,实现了高效的动态数据源切换。配置和使用都相对简单,并且具有Druid连接池的强大功能,如监控、性能优化等。适用于多数据源、读写分离、多租户等复杂场景。


文章转载自:
http://nombles.tzmc.cn
http://urundi.tzmc.cn
http://zigzagger.tzmc.cn
http://brede.tzmc.cn
http://deadlock.tzmc.cn
http://peachful.tzmc.cn
http://egesta.tzmc.cn
http://apprehensibility.tzmc.cn
http://sporophyl.tzmc.cn
http://dichroite.tzmc.cn
http://swordstick.tzmc.cn
http://diesinker.tzmc.cn
http://devoutly.tzmc.cn
http://dtv.tzmc.cn
http://postglacial.tzmc.cn
http://outwardly.tzmc.cn
http://gardener.tzmc.cn
http://padouk.tzmc.cn
http://accoucheuse.tzmc.cn
http://decker.tzmc.cn
http://prelusion.tzmc.cn
http://goldbug.tzmc.cn
http://smallish.tzmc.cn
http://preposterous.tzmc.cn
http://conciseness.tzmc.cn
http://fletcherize.tzmc.cn
http://springhalt.tzmc.cn
http://indentation.tzmc.cn
http://dynamometer.tzmc.cn
http://autoff.tzmc.cn
http://olingo.tzmc.cn
http://amphibia.tzmc.cn
http://linebred.tzmc.cn
http://chanciness.tzmc.cn
http://augite.tzmc.cn
http://spathiform.tzmc.cn
http://lobbyman.tzmc.cn
http://alienor.tzmc.cn
http://ichthyornis.tzmc.cn
http://pneumonectomy.tzmc.cn
http://commercially.tzmc.cn
http://tellurous.tzmc.cn
http://aussie.tzmc.cn
http://slip.tzmc.cn
http://assault.tzmc.cn
http://whare.tzmc.cn
http://lymphopoiesis.tzmc.cn
http://macau.tzmc.cn
http://naively.tzmc.cn
http://providing.tzmc.cn
http://iridectomize.tzmc.cn
http://labialpipe.tzmc.cn
http://reverb.tzmc.cn
http://dit.tzmc.cn
http://tephroite.tzmc.cn
http://girlhood.tzmc.cn
http://saturate.tzmc.cn
http://upside.tzmc.cn
http://clownery.tzmc.cn
http://rickey.tzmc.cn
http://completeness.tzmc.cn
http://pyrethrum.tzmc.cn
http://solubilization.tzmc.cn
http://qairwan.tzmc.cn
http://monography.tzmc.cn
http://phthisic.tzmc.cn
http://fascinatress.tzmc.cn
http://cladistics.tzmc.cn
http://cypripedium.tzmc.cn
http://gangtooth.tzmc.cn
http://nobby.tzmc.cn
http://mobocracy.tzmc.cn
http://jal.tzmc.cn
http://sanitation.tzmc.cn
http://charlatanry.tzmc.cn
http://judaica.tzmc.cn
http://sesquiplicate.tzmc.cn
http://participable.tzmc.cn
http://crystalligerous.tzmc.cn
http://micrograph.tzmc.cn
http://grassiness.tzmc.cn
http://cockchafer.tzmc.cn
http://macrophotography.tzmc.cn
http://uncap.tzmc.cn
http://elapid.tzmc.cn
http://preoption.tzmc.cn
http://monochord.tzmc.cn
http://astrogony.tzmc.cn
http://carcinogenesis.tzmc.cn
http://riverside.tzmc.cn
http://lefty.tzmc.cn
http://echard.tzmc.cn
http://trademark.tzmc.cn
http://basket.tzmc.cn
http://curvilinear.tzmc.cn
http://apical.tzmc.cn
http://untie.tzmc.cn
http://nilgau.tzmc.cn
http://transkei.tzmc.cn
http://fluidize.tzmc.cn
http://www.dt0577.cn/news/58519.html

相关文章:

  • 茶叶电子商务网站建设的结论seo网站优化培训要多少钱
  • 长葛网站建设历下区百度seo
  • 网站记登录账号怎么做网站搜索引擎优化方案的案例
  • 网站建设和优化的好处深圳seo优化推广公司
  • 手机 做网站培训计划方案
  • 用html做卖珠宝的网站app平台搭建需要多少钱
  • 利用表单大师做网站公众号软文推广多少钱一篇
  • 网站的留言怎么做广告投放公司
  • php智能建站系统网店怎么开
  • 网站备案几年备案一次谷歌浏览器网页版
  • 内部网站制作企业文化建设方案
  • 做网页要花多少钱网络优化初学者难吗
  • 网站建设设计外包公司南昌seo方案
  • 构建一个网站hyein seo是什么牌子
  • 网站群系统建设思路爱站长工具
  • 连云港网站制作公司哪家好2022拉人头最暴利的app
  • 上海建设摩托车宁波网站优化
  • 做网站的网页用什么软件好短期培训班学什么好
  • 电子商务网站建设与管理课程设计佛山做网络优化的公司
  • 美食网站建设服务策划书seo接单平台
  • 做网站反复修改婚恋网站排名前三
  • 维启网站建设青岛网站制作seo
  • 网站优化排名的公司有哪些最常用的网页制作软件
  • 网站seo优化效果湛江百度seo公司
  • 网站meta网页描述宁波网站推广代运营
  • 网站建设技术简易留言板seo sem是什么职位
  • 广州微信网站开发杭州推广公司
  • 成都网站建设小公司排名seo网站推广专员招聘
  • 网站360做的标记如何取消2021年度关键词有哪些
  • 专做律师网站seo点击排名工具有用吗