制作 spring-data-mongodb 多租户 [英] Making spring-data-mongodb multi-tenant

查看:48
本文介绍了制作 spring-data-mongodb 多租户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

帖子中去年 8 月 sbzoom 提出了使 spring-data-mongoDB 多租户的解决方案:

In a post last august sbzoom proposed a solution to make spring-data-mongoDB multi-tenant:

"你必须制作你自己的 RepositoryFactoryBean.这是来自 Spring Data MongoDB 参考文档.您仍然需要实现自己的 MongoTemplate 并延迟或删除 ensureIndexes()调用.但是您必须重写一些类以确保调用的是您的 MongoTemplate 而不是 Spring 的."

"You have to make your own RepositoryFactoryBean. Here is the example from the Spring Data MongoDB Reference Docs. You would still have to implement your own MongoTemplate and delay or remove the ensureIndexes() call. But you would have to rewrite a few classes to make sure your MongoTemplate is called instead of Spring's."

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

Did anybody implement this or something equivalent?

推荐答案

这里有很多方法可以给猫剥皮.从本质上讲,这一切都归结为您希望在哪个级别应用租赁.

There's quite a few ways to skin the cat here. It essentially all boils down to on which level you'd like to apply the tenancy.

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

The basic approach is to bind some kind of key identifying the customer on a per-thread basis, so that you can find out about the customer the current thread of execution deals with. This is usually achieved by populating a ThreadLocal with some authentication related information as you can usually derive the tenant from the logged in user.

现在,如果已到位,则可以选择在何处应用租户知识.让我简要概述最常见的:

Now if that's in place there's a few options of where to apply the tenant knowledge. Let me briefly outline the most common ones:

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

One way to separate data for multiple clients is to have individual databases per tenant. Spring Data MongoDB's core abstraction for this is the MongoDBFactory interface. The easiest way here is to override SimpleMongoDbFactory.getDb(String name) and call the parent method with the database name e.g. enriched by the tenant prefix or the like.

另一种选择是拥有租户特定的集合,例如通过租户前缀或后缀.这种机制实际上可以通过在 @Document 注释的 collectionName 属性中使用 Spring 表达式语言 (SpEl) 来利用.首先,通过 Spring bean 暴露租户前缀:

Another option is to have tenant specific collections, e.g. through tenant pre- or postfixes. This mechanism can actually be leveraged by using the Spring Expression language (SpEl) in the @Document annotation's collectionName attribute. First, expose the tenant prefix through a Spring bean:

 @Component("tenantProvider")
 public class TenantProvider {

   public String getTenantId() {
     // … implement ThreadLocal lookup here
   }
 }

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

Then use SpEL in your domain types @Document mapping:

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

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

SpEl allows you to refer to Spring beans by name and execute methods on them. MongoTemplate (and thus the repository abstraction transitively) will use the mapping metadata of the document class and the mapping subsystem will evaluate the collectionName attribute to find out about the collection to interact with.

这篇关于制作 spring-data-mongodb 多租户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆