0


Spring Boot中实现多数据源连接和切换的方案

** ❃博主首页 :**
「码到三十五」
,同名公众号 :「码到三十五」,wx号 : 「liwu0213」
☠博主专栏 :
<源码解读>

<面试攻关>

♝博主的话 :搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基


在Spring Boot中,通过

AbstractRoutingDataSource

实现多数据源连接是一种常见的做法。这种技术允许你在运行时动态地切换数据源,从而支持对多个数据库的操作。Spring Boot中配置和使用

AbstractRoutingDataSource

来实现多数据源连接。

1. 添加依赖

pom.xml

文件的依赖,比如Spring Data JPA和数据库驱动:

<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. 配置数据源属性

application.yml

application.properties

中配置多个数据源的信息。例如:

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. 创建数据源配置类

创建两个数据源配置类,分别用于配置主数据源和次数据源。

@ConfigurationpublicclassDataSourceConfig{@Bean(name ="primaryDataSource")@ConfigurationProperties(prefix ="spring.datasource.primary")publicDataSourceprimaryDataSource(){returnDataSourceBuilder.create().build();}@Bean(name ="secondaryDataSource")@ConfigurationProperties(prefix ="spring.datasource.secondary")publicDataSourcesecondaryDataSource(){returnDataSourceBuilder.create().build();}}

4. 创建自定义数据源路由类

扩展

AbstractRoutingDataSource

类,并根据上下文信息动态返回数据源。

publicclassDynamicRoutingDataSourceextendsAbstractRoutingDataSource{@OverrideprotectedObjectdetermineCurrentLookupKey(){returnDataSourceContextHolder.getDataSourceType();}}

5. 创建数据源上下文持有者

用于在运行时设置和获取当前的数据源类型。

publicclassDataSourceContextHolder{privatestaticfinalThreadLocal<String> contextHolder =newThreadLocal<>();publicstaticvoidsetDataSourceType(String dataSourceType){
        contextHolder.set(dataSourceType);}publicstaticStringgetDataSourceType(){return contextHolder.get();}publicstaticvoidclearDataSourceType(){
        contextHolder.remove();}}

6. 配置多数据源

将数据源配置到Spring上下文中,并指定默认的数据源。

@Configuration@EnableTransactionManagement@EnableJpaRepositories(
    basePackages ="com.example.repository",
    entityManagerFactoryRef ="entityManagerFactory",
    transactionManagerRef ="transactionManager")publicclassDataSourceRoutingConfig{@Autowired@Qualifier("primaryDataSource")privateDataSource primaryDataSource;@Autowired@Qualifier("secondaryDataSource")privateDataSource secondaryDataSource;@BeanpublicDataSourcedataSource(){DynamicRoutingDataSource routingDataSource =newDynamicRoutingDataSource();Map<Object,Object> targetDataSources =newHashMap<>();
        targetDataSources.put("primary", primaryDataSource);
        targetDataSources.put("secondary", secondaryDataSource);
        routingDataSource.setTargetDataSources(targetDataSources);
        routingDataSource.setDefaultTargetDataSource(primaryDataSource);return routingDataSource;}@BeanpublicLocalContainerEntityManagerFactoryBeanentityManagerFactory(EntityManagerFactoryBuilder builder){return builder
                .dataSource(dataSource()).packages("com.example.entity").persistenceUnit("multiple-pu").build();}@BeanpublicPlatformTransactionManagertransactionManager(EntityManagerFactory entityManagerFactory){returnnewJpaTransactionManager(entityManagerFactory);}}

7. 使用AOP切换数据源

通过AOP在方法执行前设置数据源类型,并在方法执行后清除。

@Aspect@ComponentpublicclassDataSourceAspect{@Before("@annotation(targetDataSource)")publicvoidchangeDataSource(JoinPoint point,TargetDataSource targetDataSource)throwsThrowable{DataSourceContextHolder.setDataSourceType(targetDataSource.value());}@After("@annotation(targetDataSource)")publicvoidclearDataSource(JoinPoint point,TargetDataSource targetDataSource){DataSourceContextHolder.clearDataSourceType();}}

自定义注解

TargetDataSource

@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public@interfaceTargetDataSource{Stringvalue();}

8. 使用自定义注解切换数据源

在需要使用特定数据源的方法或类上使用

@TargetDataSource

注解。

@ServicepublicclassUserService{@AutowiredprivateUserRepository userRepository;@TargetDataSource("primary")publicUserfindUserById(Long id){return userRepository.findById(id).orElse(null);}@TargetDataSource("secondary")publicUserfindUserBySecondaryId(Long id){// 假设secondary数据库有一个类似的表结构return userRepository.findById(id).orElse(null);}}

关注公众号[码到三十五]获取更多技术干货 !


本文转载自: https://blog.csdn.net/qq_26664043/article/details/143472554
版权归原作者 码到三十五 所有, 如有侵权,请联系我们删除。

“Spring Boot中实现多数据源连接和切换的方案”的评论:

还没有评论