SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的項(xiàng)目實(shí)踐
本文將介紹如何在 Spring Boot 應(yīng)用中實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換,包括具體實(shí)現(xiàn)步驟和示例代碼。通過本文的學(xué)習(xí),你將能夠輕松應(yīng)對(duì)多種數(shù)據(jù)源切換的場(chǎng)景,提高應(yīng)用程序的靈活性和可擴(kuò)展性。
一. 引言
在實(shí)際開發(fā)過程中,我們經(jīng)常遇到需要同時(shí)操作多個(gè)數(shù)據(jù)源的情況。例如,可能需要從不同的數(shù)據(jù)庫(kù)中讀取數(shù)據(jù),或者根據(jù)業(yè)務(wù)需求將數(shù)據(jù)寫入不同的數(shù)據(jù)庫(kù)。在這種情況下,動(dòng)態(tài)數(shù)據(jù)源切換就變得尤為重要。Spring Boot 提供了強(qiáng)大的數(shù)據(jù)源配置功能,使得動(dòng)態(tài)數(shù)據(jù)源切換變得相對(duì)簡(jiǎn)單。本文將詳細(xì)介紹如何在 Spring Boot 應(yīng)用中實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換。
二. 準(zhǔn)備工作
在開始實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換之前,我們需要做一些準(zhǔn)備工作:
1.創(chuàng)建 Spring Boot 項(xiàng)目
首先,我們需要?jiǎng)?chuàng)建一個(gè) Spring Boot 項(xiàng)目??梢允褂?Spring Initializr(https://start.spring.io/)快速生成項(xiàng)目骨架。在創(chuàng)建項(xiàng)目時(shí),選擇合適的 JDK 版本、項(xiàng)目構(gòu)建工具(如 Maven 或 Gradle)以及項(xiàng)目元數(shù)據(jù)(如項(xiàng)目名稱、描述、包名等)。
2.添加依賴
在項(xiàng)目的 pom.xml 文件中添加以下依賴:
<dependencies> <!-- Spring Boot Web 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot 數(shù)據(jù)源依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- 數(shù)據(jù)庫(kù)驅(qū)動(dòng)依賴,以 MySQL 為例 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
三. 實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換
接下來,我們將介紹如何實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換。主要分為以下幾個(gè)步驟:
1.配置數(shù)據(jù)源
在 application.properties 或 application.yml 文件中配置多個(gè)數(shù)據(jù)源,如下所示:
spring: datasource: primary: url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver secondary: url: jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
2.創(chuàng)建數(shù)據(jù)源配置類
創(chuàng)建一個(gè)數(shù)據(jù)源配置類,用于生成 DataSource 對(duì)象。這里我們使用 Java 配置的方式,如下所示:
@Configuration public class DynamicDataSourceConfig { @Primary @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource dataSource1() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource dataSource2() { return DataSourceBuilder.create().build(); } }
3.創(chuàng)建動(dòng)態(tài)數(shù)據(jù)源路由
創(chuàng)建一個(gè)動(dòng)態(tài)數(shù)據(jù)源路由類,用于根據(jù)不同的條件切換不同的數(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(); } }
4.配置數(shù)據(jù)源路由
在 application.properties 或 application.yml 文件中配置數(shù)據(jù)源路由,如下所示:
spring: datasource: type: com.zaxxer.hikari.HikariDataSource dynamic: primary: primaryDataSource secondary: secondaryDataSource
5.創(chuàng)建數(shù)據(jù)源切換切面
創(chuàng)建一個(gè)切面類,用于在方法執(zhí)行前切換數(shù)據(jù)源,在方法執(zhí)行后恢復(fù)數(shù)據(jù)源。如下所示:
@Aspect @Component public class DynamicDataSourceAspect { @Before("@annotation(TargetDataSource)") public void switchDataSource(JoinPoint point) { // 獲取方法上的注解 MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); TargetDataSource ds = method.getAnnotation(TargetDataSource.class); // 判斷注解是否為空 if (ds == null) { return; } // 切換數(shù)據(jù)源 DynamicDataSourceContextHolder.setDataSourceType(ds.name()); } @After("@annotation(TargetDataSource)") public void restoreDataSource(JoinPoint point) { // 獲取方法上的注解 MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); TargetDataSource ds = method.getAnnotation(TargetDataSource.class); // 判斷注解是否為空 if (ds == null) { return; } // 恢復(fù)數(shù)據(jù)源 DynamicDataSourceContextHolder.clearDataSourceType(); } }
6.創(chuàng)建自定義注解
創(chuàng)建一個(gè)自定義注解,用于標(biāo)記需要切換數(shù)據(jù)源的方法。如下所示:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TargetDataSource { String name(); }
7.使用自定義注解
在需要切換數(shù)據(jù)源的方法上使用自定義注解,如下所示:
@Service public class UserService { @Autowired private UserMapper userMapper; @TargetDataSource(name = "primary") public List<User> findUsersFromPrimary() { return userMapper.findAll(); } @TargetDataSource(name = "secondary") public List<User> findUsersFromSecondary() { return userMapper.findAll(); } }
四. 測(cè)試動(dòng)態(tài)數(shù)據(jù)源切換
為了驗(yàn)證我們的動(dòng)態(tài)數(shù)據(jù)源切換是否生效,我們可以編寫一些測(cè)試用例來模擬不同的數(shù)據(jù)源切換場(chǎng)景。
首先,我們需要?jiǎng)?chuàng)建一個(gè)簡(jiǎn)單的實(shí)體類和對(duì)應(yīng)的倉(cāng)庫(kù)接口:
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // 省略 getter 和 setter } public interface UserRepository extends JpaRepository<User, Long> { }
然后,我們可以編寫一個(gè)測(cè)試類來測(cè)試動(dòng)態(tài)數(shù)據(jù)源的切換:
@RunWith(SpringRunner.class) @SpringBootTest public class UserServiceTest { @Autowired private UserService userService; @Test public void testDynamicDataSource() { List<User> usersFromPrimary = userService.findUsersFromPrimary(); List<User> usersFromSecondary = userService.findUsersFromSecondary(); // 假設(shè)我們期望從主數(shù)據(jù)源和從數(shù)據(jù)源分別查詢到不同的用戶列表 assertNotNull(usersFromPrimary); assertNotNull(usersFromSecondary); assertNotEquals(usersFromPrimary, usersFromSecondary); } }
在這個(gè)測(cè)試類中,我們注入了 UserService
,并調(diào)用了兩個(gè)方法來分別從主數(shù)據(jù)源和從數(shù)據(jù)源查詢用戶列表。我們使用了 assertNotNull
和 assertNotEquals
來驗(yàn)證查詢結(jié)果,確保我們從兩個(gè)不同的數(shù)據(jù)源獲取到了不同的數(shù)據(jù)。
五. 注意事項(xiàng)
在實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換時(shí),有幾個(gè)注意事項(xiàng)需要牢記:
- 確保所有的數(shù)據(jù)源配置都是正確的,包括URL、用戶名、密碼和驅(qū)動(dòng)類名。
- 在切換數(shù)據(jù)源時(shí),要確保在操作完成后恢復(fù)到默認(rèn)數(shù)據(jù)源,以避免影響其他業(yè)務(wù)邏輯。
- 在生產(chǎn)環(huán)境中,要考慮數(shù)據(jù)源切換的性能影響,尤其是在高并發(fā)場(chǎng)景下。
- 動(dòng)態(tài)數(shù)據(jù)源切換可能會(huì)增加代碼的復(fù)雜性,因此要謹(jǐn)慎使用,確保它帶來的好處大于維護(hù)成本。
六. 總結(jié)
本文詳細(xì)介紹了在 Spring Boot 應(yīng)用中實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的方法。通過配置多個(gè)數(shù)據(jù)源、創(chuàng)建數(shù)據(jù)源路由、使用切面編程和自定義注解,我們可以在運(yùn)行時(shí)根據(jù)業(yè)務(wù)需求靈活地切換數(shù)據(jù)源。這種方法特別適合于需要同時(shí)訪問多個(gè)數(shù)據(jù)庫(kù)或數(shù)據(jù)源的應(yīng)用場(chǎng)景。雖然動(dòng)態(tài)數(shù)據(jù)源切換增加了系統(tǒng)的復(fù)雜性,但正確使用它可以為應(yīng)用帶來更高的靈活性和可擴(kuò)展性。
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot 動(dòng)態(tài)數(shù)據(jù)源切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中動(dòng)態(tài)數(shù)據(jù)源配置與使用詳解
- SpringBoot配置動(dòng)態(tài)數(shù)據(jù)源的實(shí)戰(zhàn)詳解
- SpringBoot自定義動(dòng)態(tài)數(shù)據(jù)源的流程步驟
- SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測(cè)試的操作詳解
- SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的方法總結(jié)
- springboot配置多數(shù)據(jù)源(靜態(tài)和動(dòng)態(tài)數(shù)據(jù)源)
- SpringBoot中動(dòng)態(tài)數(shù)據(jù)源是實(shí)現(xiàn)與用途
- springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid)
- springboot動(dòng)態(tài)數(shù)據(jù)源+分布式事務(wù)的實(shí)現(xiàn)
相關(guān)文章
java中建立0-10m的消息(字符串)實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猨ava中建立0-10m的消息(字符串)實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05Java 對(duì)HashMap進(jìn)行排序的三種常見方法
這篇文章主要介紹了Java 對(duì)HashMap進(jìn)行排序的三種常見方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-10-10java線程并發(fā)cyclicbarrier類使用示例
CyclicBarrier類似于CountDownLatch也是個(gè)計(jì)數(shù)器,不同的是CyclicBarrier數(shù)的是調(diào)用了CyclicBarrier.await()進(jìn)入等待的線程數(shù),當(dāng)線程數(shù)達(dá)到了CyclicBarrier初始時(shí)規(guī)定的數(shù)目時(shí),所有進(jìn)入等待狀態(tài)的線程被喚醒并繼續(xù),下面使用示例學(xué)習(xí)他的使用方法2014-01-01SpringBoot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何整合quartz實(shí)現(xiàn)定時(shí)任務(wù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-10-10基于Mybatis Plus實(shí)現(xiàn)多表分頁(yè)查詢的示例代碼
這篇文章主要介紹了基于Mybatis Plus實(shí)現(xiàn)多表分頁(yè)查詢的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

Java設(shè)計(jì)模式之Builder建造者模式