制作spring-data-mongodb多租户

nic*_*vdb 10 java spring mongodb spring-data spring-data-mongodb

去年八月sbzoom提出了一个解决方案,使弹簧的数据MongoDB的多租户:

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

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

Oli*_*ohm 16

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

基本

基本方法是在每个线程的基础上绑定某种识别客户的密钥,以便您可以了解当前执行线程所处理的客户.这通常通过填充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
   }
 }
Run Code Online (Sandbox Code Playgroud)

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

 @Document(collectionName = "#{tenantProvider.getTenantId()}_accounts"
 public class Account { … }
Run Code Online (Sandbox Code Playgroud)

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

  • 非常感谢奥利弗的及时回复。我们已经决定采用第一种方法,即数据库级别。sbzoom 提出了一个问题:“MongoTemplate 从其构造函数中运行它的 ensureIndexes() 方法。该方法调用数据库以确保数据库中存在带注释的索引。MongoTemplate 的构造函数在 Spring 启动时被调用,因此我什至没有机会设置 ThreadLocal 变量”。有什么工作可以解决这个问题? (2认同)