欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot+mybatis-plus實(shí)現(xiàn)多數(shù)據(jù)源配置的詳細(xì)步驟

 更新時(shí)間:2025年08月27日 08:51:36   作者:冰糖心書(shū)房  
在日益復(fù)雜的業(yè)務(wù)場(chǎng)景中,單一數(shù)據(jù)源往往難以滿(mǎn)足微服務(wù)架構(gòu)下的多元化需求,文將詳細(xì)介紹兩種主流的 MyBatis-Plus 多數(shù)據(jù)源配置方式,大家可以根據(jù)需要進(jìn)行選擇

MyBatis-Plus 多數(shù)據(jù)源配置詳解

在日益復(fù)雜的業(yè)務(wù)場(chǎng)景中,單一數(shù)據(jù)源往往難以滿(mǎn)足微服務(wù)架構(gòu)下的多元化需求,例如數(shù)據(jù)庫(kù)的讀寫(xiě)分離、分庫(kù)分表、以及連接不同業(yè)務(wù)模塊的獨(dú)立數(shù)據(jù)庫(kù)等。MyBatis-Plus 作為一款廣受歡迎的持久層框架,通過(guò)其強(qiáng)大的擴(kuò)展性,為開(kāi)發(fā)者提供了靈活便捷的多數(shù)據(jù)源配置方案。

本文將詳細(xì)介紹兩種主流的 MyBatis-Plus 多數(shù)據(jù)源配置方式:一種是官方推薦且廣為使用的 dynamic-datasource-spring-boot-starter 插件,另一種是基于 AOP(面向切面編程)的手動(dòng)配置方案,以幫助開(kāi)發(fā)者根據(jù)項(xiàng)目需求做出最優(yōu)選擇。

推薦方案:使用dynamic-datasource-spring-boot-starter

dynamic-datasource-spring-boot-starter 是一個(gè)由 MyBatis-Plus 團(tuán)隊(duì)成員開(kāi)源的 Spring Boot 多數(shù)據(jù)源啟動(dòng)器,它提供了豐富的功能和簡(jiǎn)便的配置,是實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的首選方案。

核心特性:

  • 數(shù)據(jù)源分組: 適用于讀寫(xiě)分離、一主多從等復(fù)雜場(chǎng)景。
  • 多種切換方式: 支持注解、AOP以及編程方式的靈活切換。
  • 動(dòng)態(tài)數(shù)據(jù)源: 支持項(xiàng)目啟動(dòng)后動(dòng)態(tài)地增加或移除數(shù)據(jù)源。
  • 組件集成: 無(wú)縫集成 MyBatis-Plus、Quartz、ShardingSphere 等多種組件。
  • 分布式事務(wù): 提供了基于 Seata 的分布式事務(wù)解決方案。

1. 引入依賴(lài)

根據(jù)您的 Spring Boot 版本,在 pom.xml 文件中引入相應(yīng)的依賴(lài):

Spring Boot 2.x:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.5.2</version> <!-- 請(qǐng)使用最新版本 -->
</dependency>

Spring Boot 3.x:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
    <version>4.2.0</version> <!-- 請(qǐng)使用最新版本 -->
</dependency>

2. 配置文件application.yml

在配置文件中定義多個(gè)數(shù)據(jù)源,并指定主數(shù)據(jù)源。

spring:
  datasource:
    dynamic:
      primary: master # 設(shè)置默認(rèn)的數(shù)據(jù)源
      strict: false # 設(shè)置為true時(shí),未匹配到數(shù)據(jù)源會(huì)報(bào)錯(cuò),設(shè)置為false則使用默認(rèn)數(shù)據(jù)源
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/db_master?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
          username: root
          password: password123
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave_1:
          url: jdbc:mysql://localhost:3306/db_slave1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
          username: root
          password: password123
          driver-class-name: com.mysql.cj.jdbc.Driver

3. 數(shù)據(jù)源切換方式

a. 注解方式(@DS)

@DS 注解是切換數(shù)據(jù)源最便捷的方式,可以作用于類(lèi)或方法上。方法上的注解優(yōu)先級(jí)高于類(lèi)上的注解。

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @DS("slave_1") // 指定使用slave_1數(shù)據(jù)源
    @Override
    public List<User> getSlaveUsers() {
        return this.list();
    }

    @Override
    public List<User> getMasterUsers() {
        // 未使用@DS注解,將使用默認(rèn)的master數(shù)據(jù)源
        return this.list();
    }
}

b. 編程方式(手動(dòng)切換)

在某些復(fù)雜的業(yè)務(wù)場(chǎng)景下,需要在代碼中動(dòng)態(tài)決定使用哪個(gè)數(shù)據(jù)源,此時(shí)可以使用 DynamicDataSourceContextHolder 進(jìn)行手動(dòng)切換。

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ProductService productService;

    @Autowired
    private StockService stockService;

    public void createOrder(String productId, int amount) {
        // 查詢(xún)商品信息,切換到slave數(shù)據(jù)源
        DynamicDataSourceContextHolder.push("slave_1");
        Product product = productService.getById(productId);
        DynamicDataSourceContextHolder.clear(); // 每次使用后必須清空

        // 扣減庫(kù)存,切換到master數(shù)據(jù)源
        DynamicDataSourceContextHolder.push("master");
        stockService.deduct(productId, amount);
        DynamicDataSourceContextHolder.clear();

        // ... 創(chuàng)建訂單等操作,使用默認(rèn)數(shù)據(jù)源
    }
}

手動(dòng)配置方案:基于 AOP 實(shí)現(xiàn)

對(duì)于希望擁有更高自由度或不愿引入額外依賴(lài)的開(kāi)發(fā)者,可以采用自定義注解和 AOP 的方式手動(dòng)實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換。其核心原理是利用 Spring 提供的 AbstractRoutingDataSource 類(lèi)。

1. 添加 AOP 依賴(lài)

pom.xml 中確保已引入 AOP 相關(guān)依賴(lài):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 自定義數(shù)據(jù)源注解

創(chuàng)建一個(gè)注解,用于在需要切換數(shù)據(jù)源的方法上進(jìn)行標(biāo)識(shí)。

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    String value();
}

3. 創(chuàng)建動(dòng)態(tài)數(shù)據(jù)源上下文

使用 ThreadLocal 存儲(chǔ)當(dāng)前線(xiàn)程需要使用的數(shù)據(jù)源名稱(chēng),以確保線(xiàn)程安全。

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();
    }
}

4. 實(shí)現(xiàn)AbstractRoutingDataSource

這是實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源的核心,通過(guò)重寫(xiě) determineCurrentLookupKey 方法,從 DynamicDataSourceContextHolder 中獲取當(dāng)前數(shù)據(jù)源的 key。

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

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceKey();
    }
}

5. 配置數(shù)據(jù)源

通過(guò) Java Config 的方式配置多個(gè)數(shù)據(jù)源,并將它們注入到 DynamicDataSource 中。

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", masterDataSource);
        targetDataSources.put("slave", slaveDataSource);

        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(masterDataSource);
        return dataSource;
    }
}

并在 application.yml 中配置相應(yīng)的數(shù)據(jù)源信息:

spring:
  datasource:
    master:
      url: jdbc:mysql://localhost:3306/db_master...
      # ...
    slave:
      url: jdbc:mysql://localhost:3306/db_slave1...
      # ...

6. 編寫(xiě) AOP 切面

創(chuàng)建切面,攔截帶有 @DataSource 注解的方法,在方法執(zhí)行前后設(shè)置和清除數(shù)據(jù)源 key。

@Aspect
@Component
public class DataSourceAspect {

    @Pointcut("@annotation(com.example.annotation.DataSource)")
    public void dataSourcePointCut() {
    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        DataSource dataSource = method.getAnnotation(DataSource.class);
        if (dataSource != null) {
            DynamicDataSourceContextHolder.setDataSourceKey(dataSource.value());
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceKey();
        }
    }
}

方案對(duì)比與選擇

特性dynamic-datasource-spring-boot-starter手動(dòng)配置 AOP
易用性高,開(kāi)箱即用,配置簡(jiǎn)單。中,需要手動(dòng)編寫(xiě)較多代碼。
功能豐富度高,支持分組、動(dòng)態(tài)數(shù)據(jù)源、分布式事務(wù)等。低,僅實(shí)現(xiàn)基礎(chǔ)的切換功能。
靈活性高,支持多種切換方式。高,完全自定義實(shí)現(xiàn),可控性強(qiáng)。
依賴(lài)引入額外 starter 依賴(lài)。無(wú)需額外依賴(lài),更為輕量。

選擇建議:

  • 對(duì)于絕大多數(shù)項(xiàng)目,特別是追求開(kāi)發(fā)效率和穩(wěn)定性的團(tuán)隊(duì),強(qiáng)烈推薦使用 dynamic-datasource-spring-boot-starter。
  • 如果項(xiàng)目對(duì)依賴(lài)有嚴(yán)格控制,或需要實(shí)現(xiàn)高度定制化的數(shù)據(jù)源切換邏輯,可以選擇 手動(dòng)配置 AOP 的方式。

注意事項(xiàng)

  • 事務(wù)管理: 在多數(shù)據(jù)源環(huán)境下,需要特別注意事務(wù)的一致性。對(duì)于單個(gè)數(shù)據(jù)源內(nèi)的事務(wù),Spring 的 @Transactional 依然有效。但對(duì)于跨多個(gè)數(shù)據(jù)源的分布式事務(wù),則需要引入如 Seata 等分布式事務(wù)解決方案。
  • AOP順序: 如果同時(shí)使用了 @Transactional@DS 注解,需要注意 AOP 的執(zhí)行順序,確保數(shù)據(jù)源切換在事務(wù)開(kāi)啟之前執(zhí)行。

通過(guò)以上兩種方案的介紹,開(kāi)發(fā)者可以根據(jù)自身項(xiàng)目的實(shí)際需求和團(tuán)隊(duì)的技術(shù)棧,選擇最合適的方式來(lái)配置和管理 MyBatis-Plus 的多數(shù)據(jù)源,從而構(gòu)建出更加健壯和可擴(kuò)展的應(yīng)用系統(tǒng)。

到此這篇關(guān)于SpringBoot+mybatis-plus實(shí)現(xiàn)多數(shù)據(jù)源配置的詳細(xì)步驟的文章就介紹到這了,更多相關(guān)SpringBoot mybatis-plus多數(shù)據(jù)源配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java常用流程控制語(yǔ)句實(shí)現(xiàn)原理解析

    Java常用流程控制語(yǔ)句實(shí)現(xiàn)原理解析

    這篇文章主要介紹了Java常用流程控制語(yǔ)句實(shí)現(xiàn)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 基于Spring概念模型:PathMatcher 路徑匹配器

    基于Spring概念模型:PathMatcher 路徑匹配器

    這篇文章主要介紹了Spring概念模型:PathMatcher 路徑匹配器,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringCloud引入feign失敗或找不到@EnableFeignClients注解問(wèn)題

    SpringCloud引入feign失敗或找不到@EnableFeignClients注解問(wèn)題

    這篇文章主要介紹了SpringCloud引入feign失敗或找不到@EnableFeignClients注解問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot如何引入緩存提高單次查詢(xún)數(shù)據(jù)效率

    SpringBoot如何引入緩存提高單次查詢(xún)數(shù)據(jù)效率

    這篇文章主要介紹了SpringBoot如何引入緩存提高單次查詢(xún)數(shù)據(jù)效率問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • SpringBoot中application.yml基本配置解讀

    SpringBoot中application.yml基本配置解讀

    文章主要介紹了Spring Boot項(xiàng)目中`application.properties`和`application.yml`配置文件的使用方法和區(qū)別,包括優(yōu)先級(jí)、配置文件所在目錄、端口服務(wù)配置、數(shù)據(jù)庫(kù)配置、多profile配置以及靜態(tài)資源路徑的指定
    2024-12-12
  • Netty中ChannelPoolHandler調(diào)用處理程序詳解

    Netty中ChannelPoolHandler調(diào)用處理程序詳解

    這篇文章主要介紹了Netty中ChannelPoolHandler調(diào)用處理程序詳解,Netty 是基于 Java NIO 的異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,使用 Netty 可以快速開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用,Netty 提供了高層次的抽象來(lái)簡(jiǎn)化 TCP 和 UDP 服務(wù)器的編程,但是你仍然可以使用底層的 API,需要的朋友可以參考下
    2023-11-11
  • java獲取網(wǎng)絡(luò)類(lèi)型的方法

    java獲取網(wǎng)絡(luò)類(lèi)型的方法

    這篇文章主要介紹了java獲取網(wǎng)絡(luò)類(lèi)型的方法,涉及java針對(duì)網(wǎng)絡(luò)類(lèi)型的參數(shù)獲取及判定技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • Kotlin lateinit與by lazy案例詳解

    Kotlin lateinit與by lazy案例詳解

    這篇文章主要介紹了Kotlin lateinit與by lazy案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • java8新特性將List中按指定屬性排序過(guò)濾重復(fù)數(shù)據(jù)的方法

    java8新特性將List中按指定屬性排序過(guò)濾重復(fù)數(shù)據(jù)的方法

    這篇文章主要介紹了java8新特性將List中按指定屬性排序過(guò)濾重復(fù)數(shù)據(jù)的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Java中斷一個(gè)線(xiàn)程操作示例

    Java中斷一個(gè)線(xiàn)程操作示例

    這篇文章主要介紹了Java中斷一個(gè)線(xiàn)程操作,結(jié)合實(shí)例形式分析了java中斷線(xiàn)程相關(guān)的interrupt()、isInterrupted()及interrupted()函數(shù)使用技巧,需要的朋友可以參考下
    2019-10-10

最新評(píng)論