SpringBoot中實現(xiàn)多數(shù)據(jù)源連接和切換的方案
引言
在Spring Boot中,通過AbstractRoutingDataSource實現(xiàn)多數(shù)據(jù)源連接是一種常見的做法。這種技術(shù)允許你在運行時動態(tài)地切換數(shù)據(jù)源,從而支持對多個數(shù)據(jù)庫的操作。Spring Boot中配置和使用AbstractRoutingDataSource來實現(xiàn)多數(shù)據(jù)源連接。
1. 添加依賴
pom.xml文件的依賴,比如Spring Data JPA和數(shù)據(jù)庫驅(qū)動:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 其他依賴 --> </dependencies>
2. 配置數(shù)據(jù)源屬性
在application.yml
或application.properties
中配置多個數(shù)據(jù)源的信息。例如:
spring: datasource: primary: url: jdbc:mysql://localhost:3306/primary_db username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver secondary: url: jdbc:mysql://localhost:3306/secondary_db username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
3. 創(chuàng)建數(shù)據(jù)源配置類
創(chuàng)建兩個數(shù)據(jù)源配置類,分別用于配置主數(shù)據(jù)源和次數(shù)據(jù)源。
@Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } }
4. 創(chuàng)建自定義數(shù)據(jù)源路由類
擴展AbstractRoutingDataSource
類,并根據(jù)上下文信息動態(tài)返回數(shù)據(jù)源。
public class DynamicRoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); } }
5. 創(chuàng)建數(shù)據(jù)源上下文持有者
用于在運行時設(shè)置和獲取當(dāng)前的數(shù)據(jù)源類型。
public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } public static String getDataSourceType() { return contextHolder.get(); } public static void clearDataSourceType() { contextHolder.remove(); } }
6. 配置多數(shù)據(jù)源
將數(shù)據(jù)源配置到Spring上下文中,并指定默認的數(shù)據(jù)源。
@Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = "com.example.repository", entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager" ) public class DataSourceRoutingConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Bean public DataSource dataSource() { DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource(); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("primary", primaryDataSource); targetDataSources.put("secondary", secondaryDataSource); routingDataSource.setTargetDataSources(targetDataSources); routingDataSource.setDefaultTargetDataSource(primaryDataSource); return routingDataSource; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder) { return builder .dataSource(dataSource()) .packages("com.example.entity") .persistenceUnit("multiple-pu") .build(); } @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
7. 使用AOP切換數(shù)據(jù)源
通過AOP在方法執(zhí)行前設(shè)置數(shù)據(jù)源類型,并在方法執(zhí)行后清除。
@Aspect @Component public class DataSourceAspect { @Before("@annotation(targetDataSource)") public void changeDataSource(JoinPoint point, TargetDataSource targetDataSource) throws Throwable { DataSourceContextHolder.setDataSourceType(targetDataSource.value()); } @After("@annotation(targetDataSource)") public void clearDataSource(JoinPoint point, TargetDataSource targetDataSource) { DataSourceContextHolder.clearDataSourceType(); } }
自定義注解TargetDataSource
:
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface TargetDataSource { String value(); }
8. 使用自定義注解切換數(shù)據(jù)源
在需要使用特定數(shù)據(jù)源的方法或類上使用@TargetDataSource
注解。
@Service public class UserService { @Autowired private UserRepository userRepository; @TargetDataSource("primary") public User findUserById(Long id) { return userRepository.findById(id).orElse(null); } @TargetDataSource("secondary") public User findUserBySecondaryId(Long id) { // 假設(shè)secondary數(shù)據(jù)庫有一個類似的表結(jié)構(gòu) return userRepository.findById(id).orElse(null); } }
到此這篇關(guān)于SpringBoot中實現(xiàn)多數(shù)據(jù)源連接和切換的方案的文章就介紹到這了,更多相關(guān)SpringBoot多數(shù)據(jù)源連接和切換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot項目如何配置多數(shù)據(jù)源
- SpringBoot實現(xiàn)JPA多數(shù)據(jù)源配置小結(jié)
- SpringBoot實現(xiàn)多數(shù)據(jù)源配置的示例詳解
- 淺析SpringBoot多數(shù)據(jù)源實現(xiàn)方案
- springboot項目實現(xiàn)多數(shù)據(jù)源配置使用dynamic-datasource-spring-boot-starter的操作步驟
- springboot配置多數(shù)據(jù)源的一款框架(dynamic-datasource-spring-boot-starter)
- SpringBoot利用dynamic-datasource-spring-boot-starter解決多數(shù)據(jù)源問題
相關(guān)文章
Spring Bean生命周期之BeanDefinition的合并過程詳解
這篇文章主要為大家詳細介紹了Spring Bean生命周期之BeanDefinition的合并過程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03淺析Java的Spring框架中IOC容器容器的應(yīng)用
這篇文章主要介紹了Java的Spring框架中IOC容器容器的應(yīng)用,包括BeanFactory容器和ApplicationContext容器的介紹,需要的朋友可以參考下2015-12-12java Spring松耦合高效應(yīng)用簡單實例分析
在Java項目,龐大的對象依賴關(guān)系將一直緊密耦合引起對象難以管理或修改。在這種情況下,可以使用Spring框架作為一個核心模塊輕松高效地管理所有的對象依賴。本文章向大家介紹Spring松耦合的實例,需要的朋友可以參考一下。2016-12-12Java中四種訪問控制權(quán)限解析(private、default、protected、public)
java當(dāng)中有4種訪問修飾限定符privat、default(默認訪問權(quán)限),protected以及public,本文就詳細的介紹一下這四種方法的具體使用,感興趣的可以了解一下2023-05-055分鐘搭建SpringCloud Eureka服務(wù)注冊中心的實現(xiàn)
這篇文章主要介紹了5分鐘搭建SpringCloud Eureka服務(wù)注冊中心的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03SpringBoot2.x過后static下的靜態(tài)資源無法訪問的問題
這篇文章主要介紹了SpringBoot2.x過后static下的靜態(tài)資源無法訪問的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01