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

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

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

前言

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

一、環(huán)境準(zhǔn)備

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

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

二、項(xiàng)目配置

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ù)庫(kù)驅(qū)動(dòng) -->
    <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 中配置多個(gè)數(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

三、實(shí)現(xiàn)動(dòng)態(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. 動(dòng)態(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. 動(dòng)態(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. 動(dòng)態(tài)數(shù)據(jù)源實(shí)現(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 切面實(shí)現(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);
    }
}

五、注意事項(xiàng)

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

六、總結(jié)

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

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

相關(guān)文章

  • 使用Java對(duì)Hbase操作總結(jié)及示例代碼

    使用Java對(duì)Hbase操作總結(jié)及示例代碼

    這篇文章主要介紹了使用Java對(duì)Hbase進(jìn)行操作總結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • springboot整合springsecurity與mybatis-plus的簡(jiǎn)單實(shí)現(xiàn)

    springboot整合springsecurity與mybatis-plus的簡(jiǎn)單實(shí)現(xiàn)

    Spring Security基于Spring開(kāi)發(fā),項(xiàng)目中如果使用Spring作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進(jìn)行整合開(kāi)發(fā)。因此作為spring全家桶中的Spring Security在java領(lǐng)域很常用
    2021-10-10
  • spring boot springjpa 支持多個(gè)數(shù)據(jù)源的實(shí)例代碼

    spring boot springjpa 支持多個(gè)數(shù)據(jù)源的實(shí)例代碼

    這篇文章主要介紹了spring boot springjpa 支持多個(gè)數(shù)據(jù)源的實(shí)例代碼,需要的朋友可以參考下
    2018-04-04
  • springboot websocket簡(jiǎn)單入門示例

    springboot websocket簡(jiǎn)單入門示例

    這篇文章主要介紹了springboot websocket簡(jiǎn)單入門示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Spring Cloud Gateway 記錄請(qǐng)求應(yīng)答數(shù)據(jù)日志操作

    Spring Cloud Gateway 記錄請(qǐng)求應(yīng)答數(shù)據(jù)日志操作

    這篇文章主要介紹了Spring Cloud Gateway 記錄請(qǐng)求應(yīng)答數(shù)據(jù)日志操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • idea導(dǎo)入配置Spring?Boot項(xiàng)目的詳細(xì)步驟教程

    idea導(dǎo)入配置Spring?Boot項(xiàng)目的詳細(xì)步驟教程

    這篇文章主要給大家介紹了關(guān)于idea導(dǎo)入配置Spring?Boot項(xiàng)目的詳細(xì)步驟,在項(xiàng)目開(kāi)發(fā)過(guò)程中,無(wú)論是導(dǎo)入運(yùn)行團(tuán)隊(duì)開(kāi)發(fā)的項(xiàng)目,還是一些開(kāi)源項(xiàng)目,還是其他的項(xiàng)目,想要在IDEA中完整的運(yùn)行起來(lái)總有很多坑,需要的朋友可以參考下
    2023-08-08
  • Docker容器中的SSH免密登錄詳解

    Docker容器中的SSH免密登錄詳解

    這篇文章主要介紹了Docker容器中的SSH免密登錄詳解,在日常的開(kāi)發(fā)和測(cè)試環(huán)境中經(jīng)常需要?jiǎng)?chuàng)建和管理Docker容器,有時(shí),出于調(diào)試或管理的目的,可能需要SSH到容器內(nèi)部,本文將介紹如何創(chuàng)建一個(gè)Docker容器,它在啟動(dòng)時(shí)自動(dòng)運(yùn)行SSH服務(wù),并支持免密登錄,需要的朋友可以參考下
    2023-08-08
  • MybatisPlus?LambdaQueryWrapper使用int默認(rèn)值的坑及解決

    MybatisPlus?LambdaQueryWrapper使用int默認(rèn)值的坑及解決

    這篇文章主要介紹了MybatisPlus?LambdaQueryWrapper使用int默認(rèn)值的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • SpringBoot FailureAnalyzer實(shí)例使用教程

    SpringBoot FailureAnalyzer實(shí)例使用教程

    FailureAnalyzer是一種在啟動(dòng)時(shí)攔截exception并將其轉(zhuǎn)換為human-readable消息的好方法,包含在故障分析中。SpringBoot為application context相關(guān)的exceptions,JSR-303驗(yàn)證等提供了這樣的分析器,實(shí)際上很容易創(chuàng)建自己的
    2022-12-12
  • Springboot中MyBatisplus使用IPage和Page分頁(yè)的實(shí)例代碼

    Springboot中MyBatisplus使用IPage和Page分頁(yè)的實(shí)例代碼

    這篇文章主要介紹了Springboot中MyBatisplus使用IPage和Page分頁(yè),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評(píng)論