前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot中实现多数据源连接和切换的方案

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

作者头像
公众号:码到三十五
发布2024-11-04 08:07:35
690
发布2024-11-04 08:07:35
举报
文章被收录于专栏:设计模式

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

1. 添加依赖

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

代码语言:javascript
复制
<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中配置多个数据源的信息。例如:

代码语言:javascript
复制
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. 创建数据源配置类

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

代码语言:javascript
复制
@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类,并根据上下文信息动态返回数据源。

代码语言:javascript
复制
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSourceType();
    }
}
5. 创建数据源上下文持有者

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

代码语言:javascript
复制
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上下文中,并指定默认的数据源。

代码语言:javascript
复制
@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在方法执行前设置数据源类型,并在方法执行后清除。

代码语言:javascript
复制
@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

代码语言:javascript
复制
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TargetDataSource {
    String value();
}
8. 使用自定义注解切换数据源

在需要使用特定数据源的方法或类上使用@TargetDataSource注解。

代码语言:javascript
复制
@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);
    }
}

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 添加依赖
  • 2. 配置数据源属性
  • 3. 创建数据源配置类
  • 4. 创建自定义数据源路由类
  • 5. 创建数据源上下文持有者
  • 6. 配置多数据源
  • 7. 使用AOP切换数据源
  • 8. 使用自定义注解切换数据源
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档