制作spring-data-mongodb多租户

在最后一个八月sbzoom的post中提出了一个使spring-data-mongoDB多租户的解决方案:

“你必须创建自己的RepositoryFactoryBean。这是Spring Data MongoDB参考文档中的示例。你仍然需要实现自己的MongoTemplate并延迟或删除ensureIndexes()调用。但是你必须重写几个类来确保调用你的MongoTemplate而不是Spring。“

有没有人实现这个或类似的东西?

有很多方法可以让猫在这里去皮。 它基本上归结为您希望应用租赁的级别。

基本

基本方法是在每个线程的基础上绑定某种识别客户的密钥,以便您可以了解当前执行线程处理的客户。 这通常通过使用一些身份validation相关信息填充ThreadLocal来实现,因为您通常可以从登录用户派生租户。

现在,如果有的话,有几个选项可以应用租户知识。 让我简要概述最常见的一些:

数据库级别的多租户

为多个客户端分隔数据的一种方法是为每个租户分配单独的数据库。 Spring Data MongoDB的核心抽象是MongoDBFactory接口。 这里最简单的方法是覆盖SimpleMongoDbFactory.getDb(String name)并使用数据库名称调用父方法,例如通过租户前缀等进行丰富。

收集级别的多租户

另一种选择是租户特定的集合,例如通过租户预先或后缀。 实际上可以通过在@Document注释的collectionName属性中使用Spring Expression语言(SpEl)来利用此机制。 首先,通过Spring bean公开租户前缀:

  @Component("tenantProvider") public class TenantProvider { public String getTenantId() { // … implement ThreadLocal lookup here } } 

然后在您的域类型@Document映射中使用SpEL:

  @Document(collectionName = "#{tenantProvider.getTenantId()}_accounts" public class Account { … } 

SpEl允许您按名称引用Spring bean并对它们执行方法。 MongoTemplate (以及MongoTemplate的存储库抽象)将使用文档类的映射元数据,映射子系统将评估collectionName属性以找出要与之交互的集合。

我和Oliver Gierke有类似的方法。 至少在数据库级别上。 https://github.com/Loki-Afro/multi-tenant-spring-mongodb您应该能够做到这样的事情:

  MultiTenantMongoDbFactory.setDatabaseNameForCurrentThread("test"); this.personRepository.save(createPerson("Phillip", "Wirth", ChronoUnit.YEARS.between( LocalDate.of(1992, Month.FEBRUARY, 3), LocalDate.now()))); System.out.println("data from test: " + this.personRepository.findAll()); // okay? fine. - lets switch the database MultiTenantMongoDbFactory.setDatabaseNameForCurrentThread("test666"); // should be empty System.out.println("data from test666: " + this.personRepository.findAll());