国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

springboot使用DynamicDataSource來動態(tài)切換數(shù)據(jù)源

這篇具有很好參考價(jià)值的文章主要介紹了springboot使用DynamicDataSource來動態(tài)切換數(shù)據(jù)源。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

DynamicDataSource是一個(gè)數(shù)據(jù)源路由器,可以根據(jù)上下文動態(tài)選擇數(shù)據(jù)源??梢栽诿總€(gè)請求或線程中將數(shù)據(jù)源設(shè)置為當(dāng)前需要使用的數(shù)據(jù).

1. 創(chuàng)建一個(gè)DynamicDataSource類來實(shí)現(xiàn)數(shù)據(jù)源路由邏輯

創(chuàng)建一個(gè)DynamicDataSource類,它繼承自AbstractRoutingDataSource。在該類中重寫**determineCurrentLookupKey()**方法,該方法返回一個(gè)字符串,用于指示當(dāng)前要使用哪個(gè)數(shù)據(jù)源

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceName();
    }

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

2. 創(chuàng)建DynamicDataSourceContextHolder線程安全類

在多線程環(huán)境下,如果多個(gè)線程同時(shí)訪問同一個(gè)方法,并且每個(gè)線程要使用不同的數(shù)據(jù)源,那么就需要對數(shù)據(jù)源進(jìn)行動態(tài)切換。如果在方法中使用一個(gè)共享的變量來存儲當(dāng)前要使用的數(shù)據(jù)源名稱,那么就會存在線程安全問題,可能會導(dǎo)致不同線程之間的數(shù)據(jù)源切換混亂,或者數(shù)據(jù)源切換不成功的情況發(fā)生。
為了解決這個(gè)問題,可以使用ThreadLocal來存儲當(dāng)前要使用的數(shù)據(jù)源名稱。ThreadLocal是一種線程本地存儲機(jī)制,它可以為每個(gè)線程提供一個(gè)獨(dú)立的變量副本,使得每個(gè)線程都可以獨(dú)立地操作自己的變量副本,而不會影響其他線程的變量副本。
在使用DynamicDataSource進(jìn)行數(shù)據(jù)源切換時(shí),每個(gè)線程都可以通過ThreadLocal來獨(dú)立地設(shè)置和獲取當(dāng)前要使用的數(shù)據(jù)源名稱,避免了多個(gè)線程之間數(shù)據(jù)源切換的混亂和不成功的情況。同時(shí),在方法執(zhí)行完畢后,使用ThreadLocal也可以避免內(nèi)存泄漏問題。
使用ThreadLocal來存儲當(dāng)前要使用的數(shù)據(jù)源名稱。**setDataSource()**方法用于設(shè)置當(dāng)前要使用的數(shù)據(jù)源名稱,**getDataSource()**方法用于獲取當(dāng)前要使用的數(shù)據(jù)源名稱,**clearDataSource()**方法用于清除當(dāng)前要使用的數(shù)據(jù)源名稱

public class DynamicDataSourceContextHolder {

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

    /**
     * 設(shè)置當(dāng)前數(shù)據(jù)源的名稱
     */
    public static void setDataSourceName(String dataSourceName) {
        contextHolder.set(dataSourceName);
    }

    /**
     * 獲取當(dāng)前數(shù)據(jù)源的名稱
     */
    public static String getDataSourceName() {
        return contextHolder.get();
    }

    /**
     * 清除當(dāng)前數(shù)據(jù)源的名稱
     */
    public static void clearDataSourceName() {
        contextHolder.remove();
    }

}

3.創(chuàng)建多數(shù)據(jù)源配置

通過yml配置,將多數(shù)據(jù)源獲取到MutilDataSourceProperties

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://****:3306/emp_ts?nullNamePatternMatchesAll=true&tinyInt1isBit=false&useSSL=false&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
    username: root
    password: root
mutil-datasource:
  connection:
    - dbName: dataSource1
      dbDriver: com.mysql.cj.jdbc.Driver
      dbUrl: jdbc:mysql://****:3306/emp_ts_1?nullNamePatternMatchesAll=true&tinyInt1isBit=false&useSSL=false&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
      dbUsername: root
      dbPassword: root
public class DbConnection {
    private String dbName;
    private String dbDialect;
    private String dbDriver;
    private String dbUrl;
    private String dbUsername;
    private String dbPassword;

    public DbConnection() {
    }

    public String getDbName() {
        return this.dbName;
    }

    public String getDbDialect() {
        return this.dbDialect;
    }

    public String getDbDriver() {
        return this.dbDriver;
    }

    public String getDbUrl() {
        return this.dbUrl;
    }

    public String getDbUsername() {
        return this.dbUsername;
    }

    public String getDbPassword() {
        return this.dbPassword;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    public void setDbDialect(String dbDialect) {
        this.dbDialect = dbDialect;
    }

    public void setDbDriver(String dbDriver) {
        this.dbDriver = dbDriver;
    }

    public void setDbUrl(String dbUrl) {
        this.dbUrl = dbUrl;
    }

    public void setDbUsername(String dbUsername) {
        this.dbUsername = dbUsername;
    }

    public void setDbPassword(String dbPassword) {
        this.dbPassword = dbPassword;
    }
}
@Configuration
@ConfigurationProperties(
    prefix = "mutil-datasource"
)
public class MutilDataSourceProperties {
    private List<DbConnection> connection = new ArrayList();

    public MutilDataSourceProperties() {
    }

    public List<DbConnection> getConnection() {
        return this.connection;
    }

    public void setConnection(List<DbConnection> connection) {
        this.connection = connection;
    }
}

4.創(chuàng)建DataSourceConfig

在配置類中創(chuàng)建默認(rèn)數(shù)據(jù)源及獲取其他多數(shù)據(jù)源進(jìn)行創(chuàng)建,默認(rèn)數(shù)據(jù)源為spring.datasource下配置的數(shù)據(jù)源

@Configuration
public class DataSourceConfig {
    @Resource
    private MutilDataSourceProperties mutilDataSourceProperties;

    public DataSourceConfig() {
    }

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource hikariDataSource(DataSourceProperties properties) {
        return DataSourceBuilder.create(properties.getClassLoader()).driverClassName(properties.determineDriverClassName()).url(properties.determineUrl()).username(properties.determineUsername()).password(properties.determinePassword()).build();
    }

    @Bean
    @Primary
    public DynamicDataSource dynamicDataSource(DataSource hikariDataSource) {
        Map<Object, Object> targetDataSources = this.createTargetDataSource();
        return new DynamicDataSource(hikariDataSource, targetDataSources);
    }

     private Map<Object, Object> createTargetDataSource() {
        Map<Object, Object> targetDataSources = new HashMap();
        List<DbConnection> connections = this.mutilDataSourceProperties.getConnection();
        connections.forEach(e -> {
            DataSource dataSource = this.createDataSource(e);
            targetDataSources.put(e.getDbName(), dataSource);
        });
        return targetDataSources;
     }

     public DataSource createDataSource(DbConnection connection) {
        return DataSourceBuilder.create().driverClassName(connection.getDbDriver()).url(connection.getDbUrl())
                .username(connection.getDbName()).password(connection.getDbPassword()).build();
     }
}

5. 使用

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    
    @Override
    public void addUser(User user) {
        DynamicDataSource.setDataSource("dataSource1");
        userMapper.insert(user);
    }

    @Override
    public void updateUser(User user) {
        DynamicDataSource.setDataSource("dataSource1");
        userMapper.updateById(user);
    }
}

6.優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 簡單易用:使用 DynamicDataSource 和 ThreadLocal 進(jìn)行動態(tài)數(shù)據(jù)源切換,配置相對簡單,易于上手。
  • 可擴(kuò)展性強(qiáng):通過繼承 AbstractRoutingDataSource 類,可以實(shí)現(xiàn)自定義的數(shù)據(jù)源路由策略。并且,由于采用了抽象類,擴(kuò)展性也比較好。
  • 線程安全:使用 ThreadLocal 來存儲當(dāng)前數(shù)據(jù)源的名稱,可以避免多線程之間數(shù)據(jù)源切換的混亂和不成功的情況。

缺點(diǎn):

  • 不能同時(shí)訪問多個(gè)數(shù)據(jù)源:在使用 DynamicDataSource 進(jìn)行動態(tài)數(shù)據(jù)源切換時(shí),同一時(shí)間只能訪問一個(gè)數(shù)據(jù)源,不能同時(shí)訪問多個(gè)數(shù)據(jù)源。

  • 執(zhí)行效率稍低:在使用 DynamicDataSource 進(jìn)行動態(tài)數(shù)據(jù)源切換時(shí),每次數(shù)據(jù)源切換都需要進(jìn)行一次路由選擇,會稍微影響執(zhí)行效率。

  • 不支持事務(wù)嵌套:在使用 DynamicDataSource 進(jìn)行動態(tài)數(shù)據(jù)源切換時(shí),如果在一個(gè)事務(wù)中需要訪問多個(gè)數(shù)據(jù)源,那么就需要進(jìn)行事務(wù)管理,而 DynamicDataSource 并不支持事務(wù)嵌套。

    綜上所述,使用 DynamicDataSource 和 ThreadLocal 進(jìn)行動態(tài)數(shù)據(jù)源切換,優(yōu)點(diǎn)是簡單易用、可擴(kuò)展性強(qiáng)、線程安全,缺點(diǎn)是不能同時(shí)訪問多個(gè)數(shù)據(jù)源、執(zhí)行效率稍低、不支持事務(wù)嵌套。在具體使用時(shí)需要根據(jù)業(yè)務(wù)場景進(jìn)行選擇。文章來源地址http://www.zghlxwxcb.cn/news/detail-446553.html

到了這里,關(guān)于springboot使用DynamicDataSource來動態(tài)切換數(shù)據(jù)源的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • SpringBoot 整合 Neo4j、MySQL 多數(shù)據(jù)源方案(Druid Mybatis DynamicDatasource)

    本文總結(jié)了Neo4j和Spring/SpringBoot、Alibaba Druid、Dynamic Datasource、Mybatis等整合方案,對相應(yīng)配置做了詳細(xì)說明。 添加Neo4j JDBC Driver依賴 添加application.yml配置 添加Neo4j JDBC Driver + Alibaba Druid依賴 添加application.yml配置 添加Neo4j JDBC Driver、Alibaba Druid、Dynamic DataSource依賴 添加application.y

    2023年04月08日
    瀏覽(19)
  • SpringBoot整合Druid數(shù)據(jù)庫連接池&多數(shù)據(jù)源&注解切換&動態(tài)添加

    配置好之后 Druid 會通過 DruidDataSourceAutoConfigure 自動裝配 屬性配置 數(shù)據(jù)源枚舉 動態(tài)數(shù)據(jù)源 繼承 AbstractRoutingDataSource 就可以實(shí)現(xiàn)動態(tài)數(shù)據(jù)源了 實(shí)現(xiàn)了一個(gè)動態(tài)數(shù)據(jù)源類的構(gòu)造方法,主要是為了設(shè)置默認(rèn)數(shù)據(jù)源,以及以Map保存的各種目標(biāo)數(shù)據(jù)源。其中Map的key是設(shè)置的數(shù)據(jù)源名稱

    2024年03月22日
    瀏覽(34)
  • SpringBoot整合多數(shù)據(jù)源,并支持動態(tài)新增與切換(詳細(xì)教程)

    SpringBoot整合多數(shù)據(jù)源,并支持動態(tài)新增與切換(詳細(xì)教程)

    推薦文章: ????1、springBoot對接kafka,批量、并發(fā)、異步獲取消息,并動態(tài)、批量插入庫表; ????2、SpringBoot用線程池ThreadPoolTaskExecutor異步處理百萬級數(shù)據(jù); ????3、java后端接口API性能優(yōu)化技巧 ????4、SpringBoot+MyBatis流式查詢,處理大規(guī)模數(shù)據(jù),提高系統(tǒng)的性能和響應(yīng)能力。 一

    2024年02月10日
    瀏覽(25)
  • 基于注解切換、Hikari實(shí)現(xiàn)的SpringBoot動態(tài)數(shù)據(jù)源(支持JNDI)

    先說效果,要實(shí)現(xiàn)方法級別注解切換當(dāng)前數(shù)據(jù)源,不設(shè)置注解時(shí)走默認(rèn)數(shù)據(jù)源,同時(shí)支持JNDI源。 Spring框架中存在一個(gè)抽象類 AbstractRoutingDataSource ,他是一個(gè)可以動態(tài)選擇當(dāng)前DataSource的路由類,我們就是要從這里入手,重新實(shí)現(xiàn)數(shù)據(jù)源的切換選擇邏輯。然后借助注解和切面,

    2024年02月08日
    瀏覽(33)
  • springboot dynamic-datasource 實(shí)現(xiàn)動態(tài)切換數(shù)據(jù)源-多租戶-配置文件切換-基于dynamic-datasource

    1、實(shí)現(xiàn)動態(tài)切換數(shù)據(jù)源 2、實(shí)現(xiàn)配置多數(shù)據(jù)源 3、實(shí)現(xiàn)讀寫分離也可以用多數(shù)據(jù)源方式 4、選擇 dynamic-datasource集成了很多ORM的框架,其中,使用比較多的是druid,但有一些東西開始收費(fèi)了 druid也可以自行配置,配置多了點(diǎn) 目前版本只支持單一位置加載數(shù)據(jù)源(只能從配置文件或

    2024年02月09日
    瀏覽(18)
  • 使用mybatis和dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源操作數(shù)據(jù)庫

    記錄 :415 場景 :使用mybatis和dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源操作數(shù)據(jù)庫。 版本 :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 :一個(gè)基于springboot的快

    2023年04月19日
    瀏覽(23)
  • 使用dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源操作數(shù)據(jù)庫(MyBatis-3.5.9)

    記錄 :383 場景 :使用dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源,使用MyBatis操作數(shù)據(jù)庫。提供三種示例:一,使用@DS注解作用到類上。二,使用@DS注解作用到方法上。三,不使用注解,使用DynamicDataSourceContextHolder類在方法內(nèi)靈活切換不同數(shù)據(jù)源。 源碼: https://github.com/

    2024年01月20日
    瀏覽(25)
  • mybatisplus快速實(shí)現(xiàn)動態(tài)數(shù)據(jù)源切換

    1.背景 ? 通常一個(gè)系統(tǒng)只需要連接一個(gè)數(shù)據(jù)庫就可以了。但是在企業(yè)應(yīng)用的開發(fā)中往往會和其他子系統(tǒng)交互,特別是對于一些數(shù)據(jù)實(shí)時(shí)性要求比較高的數(shù)據(jù),我們就需要做實(shí)時(shí)連接查詢,而不是做同步。這個(gè)時(shí)候就需要用到多數(shù)據(jù)源。 ? 舉個(gè)簡單的例子某企業(yè)要做訂單網(wǎng)上訂

    2024年02月06日
    瀏覽(25)
  • 實(shí)例講解Spring boot動態(tài)切換數(shù)據(jù)源

    摘要: 本文模擬一下在主庫查詢訂單信息查詢不到的時(shí)候,切換數(shù)據(jù)源去歷史庫里面查詢。 本文分享自華為云社區(qū)《springboot動態(tài)切換數(shù)據(jù)源》,作者:小陳沒煩惱 。 在公司的系統(tǒng)里,由于數(shù)據(jù)量較大,所以配置了多個(gè)數(shù)據(jù)源,它會根據(jù)用戶所在的地區(qū)去查詢那一個(gè)數(shù)據(jù)庫

    2024年02月06日
    瀏覽(26)
  • springboot,多數(shù)據(jù)源切換

    需求介紹: ????????要求做一個(gè)平臺,有其他第三方系統(tǒng)接入;每個(gè)系統(tǒng)有自己的數(shù)據(jù)源配置,通過調(diào)用平臺接口,實(shí)現(xiàn)將數(shù)據(jù)保存到第三方自己的數(shù)據(jù)庫中; 實(shí)現(xiàn)過程: ? ? ? ? 1.在平臺項(xiàng)目運(yùn)行時(shí),通過接口獲取每個(gè)第三方系統(tǒng)的數(shù)據(jù)源;以key-value的形式保存到全局

    2024年02月16日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包