标签:datasource spring-boot spring-data-jpa spring
因此,我有一个使用JavaConfig和JPA来连接服务和存储库的相当标准的Spring Boot应用程序.但是,该应用程序的一个非标准方面是需要按需启动隔离的云数据库,以出于法律原因将客户端数据分开.
我有一个简单的ClientService,其中注入了一些存储库,我的目标是创建某种工厂,可以在其中请求该ClientService的版本(特定于每个客户端),该版本向所有存储库中注入了自定义数据源. Spring Boot通常对于将事物连接起来非常有用,但由于它很难看到幕后发生的事情,因此使事情变得更加混乱.
解决此问题的最佳方法是什么?我的第一个想法是使用方法getClientService(Client client)的名为ClientServiceFactory的bean.我很容易为该客户端创建自定义数据源-困难的部分是如何返回ClientService的实例,并自动注入所有其他内容,但强制所有存储库Bean使用此数据源.自然,ClientService将不再是单例,而是我将在内部存储Client>客户服务.
任何帮助或建议,将不胜感激.
解决方法:
我相信您将需要实施多租户方法.
我在Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres上发表过关于这个话题的博客
基本上,这是为多租户配置持久层的步骤:
> 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.
标签:datasource,spring-boot,spring-data-jpa,spring 来源: https://codeday.me/bug/20191111/2019299.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。