最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 3.4.0 結(jié)合 Mybatis-plus 實現(xiàn)動態(tài)數(shù)據(jù)源的完整方案

 更新時間:2025年04月01日 10:01:17   作者:Joyous  
本文詳細介紹了在 Spring Boot 3.4.0 項目中結(jié)合 Mybatis-plus 實現(xiàn)動態(tài)數(shù)據(jù)源切換的完整方案,通過自定義注解和AOP切面,我們可以優(yōu)雅地實現(xiàn)方法級別的數(shù)據(jù)源切換,滿足多數(shù)據(jù)源場景下的各種需求,感興趣的朋友一起看看吧

前言

在實際企業(yè)級應(yīng)用開發(fā)中,多數(shù)據(jù)源的需求非常常見。本文將詳細介紹如何在 Spring Boot 3.4.0 項目中結(jié)合 Mybatis-plus 實現(xiàn)動態(tài)數(shù)據(jù)源切換功能。

一、環(huán)境準備

首先確保你的開發(fā)環(huán)境滿足以下要求:

  • JDK 17+
  • Spring Boot 3.4.0
  • Mybatis-plus 3.5.3.1+
  • Maven 3.6.3+

二、項目配置

1. 添加依賴

pom.xml 中添加以下依賴:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Mybatis-plus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <!-- 數(shù)據(jù)庫驅(qū)動 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- 其他工具 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

2. 配置文件

application.yml 中配置多個數(shù)據(jù)源:

spring:
  datasource:
    master:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/master_db?useSSL=false&serverTimezone=UTC
      username: root
      password: 123456
    slave1:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/slave1_db?useSSL=false&serverTimezone=UTC
      username: root
      password: 123456
    slave2:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/slave2_db?useSSL=false&serverTimezone=UTC
      username: root
      password: 123456

三、實現(xiàn)動態(tài)數(shù)據(jù)源

1. 數(shù)據(jù)源枚舉

public enum DataSourceType {
    MASTER("master"),
    SLAVE1("slave1"),
    SLAVE2("slave2");
    private final String name;
    DataSourceType(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

2. 動態(tài)數(shù)據(jù)源上下文

public class DynamicDataSourceContextHolder {
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
    public static void setDataSourceType(String dataSourceType) {
        CONTEXT_HOLDER.set(dataSourceType);
    }
    public static String getDataSourceType() {
        return CONTEXT_HOLDER.get();
    }
    public static void clearDataSourceType() {
        CONTEXT_HOLDER.remove();
    }
}

3. 動態(tài)數(shù)據(jù)源配置

@Configuration
@MapperScan(basePackages = "com.example.mapper")
public class DynamicDataSourceConfig {
    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.slave1")
    public DataSource slave1DataSource() {
        return DataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.slave2")
    public DataSource slave2DataSource() {
        return DataSourceBuilder.create().build();
    }
    @Bean
    public DataSource dynamicDataSource() {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.getName(), masterDataSource());
        targetDataSources.put(DataSourceType.SLAVE1.getName(), slave1DataSource());
        targetDataSources.put(DataSourceType.SLAVE2.getName(), slave2DataSource());
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
        return dynamicDataSource;
    }
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

4. 動態(tài)數(shù)據(jù)源實現(xiàn)

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

5. 自定義注解

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

6. AOP 切面實現(xiàn)

@Aspect
@Component
@Order(-1)
@Slf4j
public class DataSourceAspect {
    @Pointcut("@annotation(com.example.annotation.DataSource)" +
            "|| @within(com.example.annotation.DataSource)")
    public void dsPointCut() {
    }
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        DataSource dataSource = getDataSource(point);
        if (dataSource != null) {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().getName());
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }
    private DataSource getDataSource(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (dataSource != null) {
            return dataSource;
        }
        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}

四、使用示例

1. Service 層使用

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    @DataSource(DataSourceType.MASTER)
    public User getMasterUser(Long id) {
        return userMapper.selectById(id);
    }
    @Override
    @DataSource(DataSourceType.SLAVE1)
    public User getSlave1User(Long id) {
        return userMapper.selectById(id);
    }
    @Override
    @DataSource(DataSourceType.SLAVE2)
    public User getSlave2User(Long id) {
        return userMapper.selectById(id);
    }
}

2. Controller 層調(diào)用

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/master/{id}")
    public User master(@PathVariable Long id) {
        return userService.getMasterUser(id);
    }
    @GetMapping("/slave1/{id}")
    public User slave1(@PathVariable Long id) {
        return userService.getSlave1User(id);
    }
    @GetMapping("/slave2/{id}")
    public User slave2(@PathVariable Long id) {
        return userService.getSlave2User(id);
    }
}

五、注意事項

  • 事務(wù)管理:動態(tài)數(shù)據(jù)源切換與事務(wù)管理需要特別注意,建議在事務(wù)方法中不要切換數(shù)據(jù)源
  • 連接池配置:可以為每個數(shù)據(jù)源單獨配置連接池參數(shù)
  • 性能考慮:頻繁切換數(shù)據(jù)源可能會影響性能,應(yīng)根據(jù)實際需求合理設(shè)計
  • 異常處理:做好數(shù)據(jù)源切換失敗時的異常處理

六、總結(jié)

本文詳細介紹了在 Spring Boot 3.4.0 項目中結(jié)合 Mybatis-plus 實現(xiàn)動態(tài)數(shù)據(jù)源切換的完整方案。通過自定義注解和AOP切面,我們可以優(yōu)雅地實現(xiàn)方法級別的數(shù)據(jù)源切換,滿足多數(shù)據(jù)源場景下的各種需求。

到此這篇關(guān)于Spring Boot 3.4.0 結(jié)合 Mybatis-plus 實現(xiàn)動態(tài)數(shù)據(jù)源的完整方案的文章就介紹到這了,更多相關(guān)Spring Boot Mybatis-plus動態(tài)數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復雜操作實例詳解

    MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復雜操作實例詳解

    MyBatis-Plus是一個MyBatis的增強工具,提供快速開發(fā)單表CRUD操作等功能,通過依賴引入和配置,可以快速創(chuàng)建和使用Mapper接口進行數(shù)據(jù)庫操作,這篇文章通過實例代碼介紹MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復雜操作,感興趣的朋友一起看看吧
    2026-02-02
  • JavaWeb學習筆記分享(必看篇)

    JavaWeb學習筆記分享(必看篇)

    下面小編就為大家?guī)硪黄狫avaWeb學習筆記分享(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • 解析和解決org.springframework.beans.factory.NoSuchBeanDefinitionException異常問題

    解析和解決org.springframework.beans.factory.NoSuchBeanDefinitionE

    這篇文章主要介紹了解析和解決org.springframework.beans.factory.NoSuchBeanDefinitionException異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java 調(diào)整格式日志輸出

    Java 調(diào)整格式日志輸出

    本文主要介紹Java 的日志輸出格式,在開發(fā)java的時候會經(jīng)??慈罩具M行調(diào)試或者查看錯誤,這里給大家介紹日志輸出調(diào)整格式,以便大家看日志的時候更加方便,
    2016-07-07
  • Myeclipse清理項目緩存的幾大方法

    Myeclipse清理項目緩存的幾大方法

    今天小編就為大家分享一篇關(guān)于Myeclipse清理項目緩存的幾大方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • java 頁面url傳值中文亂碼的解決方法

    java 頁面url傳值中文亂碼的解決方法

    本節(jié)講的是ajax 的URL參數(shù)中有中文值,傳到服務(wù)端,在用request.getParameter()方法,得到的常常會是亂碼。
    2013-03-03
  • Spring Boot 表單驗證篇

    Spring Boot 表單驗證篇

    在表單提交的時候,我們需要進行驗證。下面通過本篇文章給大家介紹Spring Boot 表單驗證篇,需要的朋友可以參考下
    2017-08-08
  • Java并發(fā)編程示例(六):等待線程執(zhí)行終止

    Java并發(fā)編程示例(六):等待線程執(zhí)行終止

    這篇文章主要介紹了Java并發(fā)編程示例(六):等待線程執(zhí)行終止,在本節(jié),示例程序演示等待初始化方法完成后,再去執(zhí)行其他任務(wù),需要的朋友可以參考下
    2014-12-12
  • Mybatis核心配置文件加載流程詳解

    Mybatis核心配置文件加載流程詳解

    本文將介紹MyBatis在配置文件加載的過程中,如何加載核心配置文件、如何解析映射文件中的SQL語句以及每條SQL語句如何與映射接口的方法進行關(guān)聯(lián),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Java利用Optional解決空指針異常

    Java利用Optional解決空指針異常

    這篇文章主要介紹了Java利用Optional解決空指針異常,Optional?類是一個包含有可選值的包裝類,這意味著?Optional?類既可以含有對象也可以為空
    2022-09-09

最新評論

舞钢市| 三原县| 隆德县| 毕节市| 镇宁| 仪征市| 永德县| 鄂伦春自治旗| 宜城市| 宜阳县| 延庆县| 绵竹市| 镇江市| 六盘水市| 台山市| 左云县| 左云县| 青河县| 伊金霍洛旗| 龙陵县| 九龙城区| 普格县| 南木林县| 安塞县| 鄯善县| 壶关县| 阜宁县| 星座| 建湖县| 盖州市| 甘南县| 霍邱县| 文水县| 巴马| 广宗县| 莫力| 江门市| 庆安县| 溧阳市| 正宁县| 泗洪县|