基于集合的多租户Spring数据mongo

时间:2013-03-31 10:15:38

标签: spring mongodb spring-data spring-data-mongodb

我正在Spring数据mongodb中启动一个MULTI-TENANT项目。 阅读此post后,每个租户的收集在mongodb中是一个相当不错的方法。

那么我怎样才能在Spring Data Mongo中实现这一目标?显然,没有提供开箱即用的解决方案,但我认为我可以通过覆盖determineCollectionName方法来调整MongoTemplate,但我认为它不是用于公共目的的受保护方法。

但是,我通过按照提供的提示here扩展SimpleMongoDbFactory并使用LocalThread变量,非常容易地为每个租户方法设置数据库。

所以,问题是:

  1. 我是否可以通过覆盖集合和域类名称映射的安全方式? p.s:这应该在运行时发生,所以我认为@collection注释根本没用。
  2. 如果每个租户的收集是不可能的,那么采用多分贝方法可以获得多少性能和资源惩罚?

1 个答案:

答案 0 :(得分:0)

您可以扩展MappingMongoEntityInformation以覆盖getCollectionName()。存储库操作在每个操作上调用getCollectionName()。我假设tenantId是ThreadLocal

public class TenantThreadLocal extends ThreadLocal<String> {
    private final static TenantThreadLocal instance = new TenantThreadLocal();

    public static TenantThreadLocal instance() {
        return instance;
    }
}

省略了构造函数的重写类。

public class TenantMappingMongoEntityInformation<T, ID extends java.io.Serializable>  extends MappingMongoEntityInformation<T, ID> {

    @Override
    public String getCollectionName() {
        return TenantThreadLocal.instance().get() + super.getCollectionName();
    }
}

然后创建您的存储库:

MongoPersistentEntity<YourObject> persistentEntity = 
    (MongoPersistentEntity<YourObject>) 
    mongoOperations.getConverter()
    .getMappingContext()
    .getPersistentEntity(YourObject.class);

MongoEntityInformation<YourObject, ObjectId> mongoEntityInformation =
    new MappingMongoEntityInformation<YourObject, ObjectId>(persistentEntity);

CrudRepository<YourObject, ObjectId> repository =
    new SimpleMongoRepository<YourObject, ObjectId>(mongoEntityInformation, mongoOperations);