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

 更新时间:2024年11月04日 08:26:15   作者:码到三十五  
在Spring Boot中,通过AbstractRoutingDataSource实现多数据源连接是一种常见的做法,这种技术允许你在运行时动态地切换数据源,从而支持对多个数据库的操作,本文给大家介绍了SpringBoot中实现多数据源连接和切换的方案,需要的朋友可以参考下

引言

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

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

@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. 创建自定义数据源路由类

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

public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSourceType();
    }
}

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

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

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

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

@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切换数据源

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

@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. 使用自定义注解切换数据源

在需要使用特定数据源的方法或类上使用@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) {
        // 假设secondary数据库有一个类似的表结构
        return userRepository.findById(id).orElse(null);
    }
}

到此这篇关于SpringBoot中实现多数据源连接和切换的方案的文章就介绍到这了,更多相关SpringBoot多数据源连接和切换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis-plus分页查询的实现示例

    mybatis-plus分页查询的实现示例

    这篇文章主要介绍了mybatis-plus分页查询的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • SpringBoot注册第三方Bean的方法总结

    SpringBoot注册第三方Bean的方法总结

    众所周知,SpringBoot默认会扫描启动类所在的包及其子包,一般我们都是在需要的类上通过注解的方式去将Bean注册交给IOC进行管理,但是注册第三方Bean的方案却不支持,所以本文给大家介绍了SpringBoot注册第三方Bean的方法,需要的朋友可以参考下
    2024-01-01
  • java图形化界面实现登录窗口

    java图形化界面实现登录窗口

    这篇文章主要为大家详细介绍了java图形化界面实现登录窗口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Java C++题解leetcode消失的两个数字实例

    Java C++题解leetcode消失的两个数字实例

    这篇文章主要介绍了Java C++题解leetcode消失的两个数字实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • GSON实现Java对象与JSON格式对象相互转换的完全教程

    GSON实现Java对象与JSON格式对象相互转换的完全教程

    GSON是Google编写并在在GitHub上开源的Java序列化与反序列化JSON的类库,今天我们就来总结一下使用GSON实现Java对象与JSON格式对象相互转换的完全教程
    2016-06-06
  • Java中list.contains()的用法及拓展

    Java中list.contains()的用法及拓展

    List集合相信大家在开发过程中几乎都会用到,有时候难免会遇到集合里的数据是重复的,需要进行去除,下面这篇文章主要给大家介绍了关于Java中list.contains()的用法及拓展的相关资料,需要的朋友可以参考下
    2023-03-03
  • spring项目实现国际化流程解析

    spring项目实现国际化流程解析

    SpringBoot实现国际化(i18n)的步骤包括创建国际化资源文件、配置application.yml、自定义LocaleResolver和LocaleChangeInterceptor、在代码中使用MessageSource获取国际化消息,本文介绍spring项目实现国际化流程,感兴趣的朋友一起看看吧
    2026-01-01
  • java spark文件读取乱码问题的解决方法

    java spark文件读取乱码问题的解决方法

    这篇文章主要为大家详细介绍了java spark文件读取乱码问题的相关解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-10-10
  • SpringBoot使用CORS实现无缝跨域的方法实现

    SpringBoot使用CORS实现无缝跨域的方法实现

    CORS 是一种在服务端设置响应头部信息的机制,允许特定的源进行跨域访问,本文主要介绍了SpringBoot使用CORS实现无缝跨域的方法实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • 如何加密配置文件里的敏感数据

    如何加密配置文件里的敏感数据

    这篇文章主要介绍了加密配置文件里的敏感数据的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论