gpt4 book ai didi

spring - 如何使用自定义数据源动态连接存储库?

转载 作者:行者123 更新时间:2023-12-04 03:06:15 25 4
gpt4 key购买 nike

所以我有一个相当标准的 Spring Boot 应用程序,它使用 JavaConfig 和 JPA 来连接服务和存储库。但是,出于法律原因,该应用程序的一个非标准方面是要求按需启动独立的云数据库以保持客户数据独立。

我有一个简单的 ClientService,其中注入(inject)了一些存储库,我的目标是创建某种类型的工厂,我可以在其中请求此 ClientService 的一个版本,特定于每个客户端,它具有注入(inject)到所有存储库的自定义数据源。 Spring Boot 通常非常适合连接事物,但它让事情变得更加困惑,因为很难看出幕后发生了什么。

处理此问题的最佳方法是什么?我的第一个想法是使用方法 getClientService(Client client) 的名为 ClientServiceFactory 的 bean。为这个客户端创建自定义数据源对我来说很容易——困难的部分是我如何返回一个 ClientService 实例,所有其他的东西都自动注入(inject),但强制所有存储库 bean 使用这个数据源。自然地,ClientService 将不再是单例,而是我将在 Client > ClientService 内部存储一个映射。

如有任何帮助或建议,我们将不胜感激。

最佳答案

我相信您需要实现 Multi-Tenancy 方法。

我在博客上写了这个主题:Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres

基本上,这是为 Multi-Tenancy 配置持久层的步骤:

  • Hibernate、JPA 和数据源属性:

application.yml

...
multitenancy:
dvdrental:
dataSources:
-
tenantId: TENANT_01
url: jdbc:postgresql://172.16.69.133:5432/db_dvdrental
username: user_dvdrental
password: changeit
driverClassName: org.postgresql.Driver
-
tenantId: TENANT_02
url: jdbc:postgresql://172.16.69.133:5532/db_dvdrental
username: user_dvdrental
password: changeit
driverClassName: org.postgresql.Driver
...

MultiTenantJpaConfiguration.java

 ...
@Configuration
@EnableConfigurationProperties({ MultiTenantDvdRentalProperties.class, JpaProperties.class })
@ImportResource(locations = { "classpath:applicationContent.xml" })
@EnableTransactionManagement
public class MultiTenantJpaConfiguration {

@Autowired
private JpaProperties jpaProperties;

@Autowired
private MultiTenantDvdRentalProperties multiTenantDvdRentalProperties;
...
}

MultiTenantDvdRentalProperties.java

...
@Configuration
@ConfigurationProperties(prefix = "multitenancy.dvdrental")
public class MultiTenantDvdRentalProperties {

private List<DataSourceProperties> dataSourcesProps;
// Getters and Setters

public static class DataSourceProperties extends org.springframework.boot.autoconfigure.jdbc.DataSourceProperties {

private String tenantId;
// Getters and Setters
}
}
  • 数据源 bean :

MultiTenantJpaConfiguration.java

 ...
public class MultiTenantJpaConfiguration {
...
@Bean(name = "dataSourcesDvdRental" )
public Map<String, DataSource> dataSourcesDvdRental() {
...
}
...
}
  • 实体管理器工厂 bean:

MultiTenantJpaConfiguration.java

 ...
public class MultiTenantJpaConfiguration {
...
@Bean
public MultiTenantConnectionProvider multiTenantConnectionProvider() {
...
}

@Bean
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
...
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(MultiTenantConnectionProvider multiTenantConnectionProvider,
CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
...
}
...
}
  • 事务管理器 bean:

MultiTenantJpaConfiguration.java

 ...
public class MultiTenantJpaConfiguration {
...
@Bean
public EntityManagerFactory entityManagerFactory(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
...
}

@Bean
public PlatformTransactionManager txManager(EntityManagerFactory entityManagerFactory) {
...
}
...
}
  • Spring Data JPA 和事务支持配置:

applicationContent.xml

...
<jpa:repositories base-package="com.asimio.dvdrental.dao" transaction-manager-ref="txManager" />
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
...

ActorDao.java

public interface ActorDao extends JpaRepository<Actor, Integer> {
}

根据您的需要,可以这样做:

...
@Autowired
private ActorDao actorDao;
...

DvdRentalTenantContext.setTenantId("TENANT_01");
this.actorDao.findOne(...);
...

// Or
DvdRentalTenantContext.setTenantId("TENANT_02");
this.actorDao.save(...);
...

可以通过将要执行 JPA 操作的 ThreadLocal 在 servlet 过滤器/Spring MVC 拦截器/线程中设置 tenantId 等。

关于spring - 如何使用自定义数据源动态连接存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44055447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com