ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

春季-如何通过自定义数据源动态连接存储库?

2019-11-11 10:19:26  阅读:245  来源: 互联网

标签: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. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有