【问题标题】:Multi-tenant mongodb database based with spring data基于spring数据的多租户mongodb数据库
【发布时间】:2013-12-26 21:44:12
【问题描述】:

我想制作使用 mongodb 和 spring-data 多租户的 Web 应用程序。

基本上我想将我所有的实体(集合)复制到不同的数据库中。然后(基于某些规则,例如登录系统的用户)我想将一些实体实例(文档)存储到正确的数据库中。

例如,我有一个名为 DBNameProviderService.getDbName() 的服务,它动态地返回数据库的名称。如何使用此服务动态选择正确的 Db?

已编辑

如果不够清楚,请见谅。也许举个例子会更清楚。

在我的系统中,我可以注册/登录用户(他们存储在名为 general_db 的数据库中的用户集合中)。

我还有一个实体 A(标记为多租户,只是扩展了一个接口)。如果我以 User1 身份登录,我想始终将 A 实例存储在集合 A 的数据库 User1_db 中,而如果我以 User2 身份登录,我想将 A 实例存储在集合 A 的 User2_db 中。

所以在这种情况下,问题是我不能为每个用户创建一个 mongotemplate bean,因为用户可以在系统中注册,所以它是动态的。我需要 MongoTemplate 动态选择数据库。

【问题讨论】:

  • 我不明白问题是什么以及您需要什么帮助。您的函数将根据输入值返回正确的数据库。
  • @WiredPrairie 我更新了问题,如果现在问题更清楚了,请查看。提前致谢

标签: spring mongodb spring-data-mongodb


【解决方案1】:

你应该看看我的 github 项目,我有一个非常相似的问题。

https://github.com/Loki-Afro/multi-tenant-spring-mongodb

【讨论】:

    【解决方案2】:

    查看相同类型的问题Spring-data-mongodb connect to multiple databases in one Mongo instance 也可以分片并将您想要使用和搜索的 id 设置为键的一部分。

    【讨论】:

      【解决方案3】:

      我在使用 spring mongodb 作为多租户时也遇到了类似的问题。最后,我想出了一种方法,使用适配器来管理静态集合中的 MongoTemplates。

      SpringMongoConfigAdapater 是一个示例 sn-p,可以帮助进行概述。

      弹簧配置:

      <bean id="springConfig"  class="com.company.config.SpringMongoConfigAdapater"  >
      
      <!-- default db initialization -->
      
          <property name="defaultDBName" value="${MONGOHQ_DB:db}"></property> 
      
      <!-- mongo instance is referred to http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd  -->
      
           <property name="mongo" ref="mongo"></property>
      
              </bean>
      

      SpringMongoConfigAdapter:

      public class SpringMongoConfigAdapater {
         // Each Tenant is referenced to MongoTemplate
       static HashMap<String, MongoTemplate> templateMap = new HashMap<>();
       // Each Tenant is referenced to GridFS Template
          static  HashMap<String, GridFsTemplate> gridfsMap = new HashMap<>();
          // @Autowired
          Mongo mongo;
          @Autowired
          private MongoConverter mappingMongoConverter;
          public HashMap<String, MongoTemplate> getTemplateMap() {
              return templateMap;
          }
          /**
           * @return the defaultDBName
           */
          public String getDefaultDBName() {
              return defaultDBName;
          }   /**
           * @param defaultDBName the defaultDBName to set
           */
          public void setDefaultDBName(String defaultDBName) {
              this.defaultDBName = defaultDBName;
          }
          String defaultDBName;
          @Produces
          @ApplicationScoped
          public MongoTemplate templateManager() throws Exception {
              String dbName = MyThreadLocal.getDBName();
              if (StringUtils.isBlank(dbName)) {
                  dbName = defaultDBName;
              }
              if (templateMap.get(dbName) == null) {
                  MongoTemplate template = mongoTemplate(dbName);
                  templateMap.put(dbName, template);
              }
              return templateMap.get(dbName);
          }
          //this is for gridfs template.
          public GridFsTemplate gridfsTemplateManager() throws Exception {
              String dbName = MyThreadLocal.getDBName();
              if (StringUtils.isBlank(dbName)) {
                  dbName = defaultDBName;
              }
              if (gridfsMap.get(dbName) == null) {
                  GridFsTemplate template = new GridFsTemplate(mongoDbFactory(dbName), mappingMongoConverter);
                  gridfsMap.put(dbName, template);
              }
              return gridfsMap.get(dbName);
          }
          MongoTemplate mongoTemplate(String name) throws Exception {
              MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(name));
              return mongoTemplate;
          }
          MongoDbFactory mongoDbFactory(String name) throws Exception {
              return new SimpleMongoDbFactory(mongo, name);
          }
          /**
           * @return the gridfsMap
           */
          public HashMap<String, GridFsTemplate> getGridfsMap() {
              return gridfsMap;
          }
          /**
           * @param gridfsMap the gridfsMap to set
           */
          public void setGridfsMap(HashMap<String, GridFsTemplate> gridfsMap) {
              this.gridfsMap = gridfsMap;
          }
      }
      

      现在从您的代码调用时,

       springMongoConfigAdapater .templateManager().getMongoOps().findAll(User.class); 
      

      最重要的是,使用 ThreadLocal 来初始化 MultiTenant Identifier(可以是 dbName) 我提供了详细信息,可能会对您有所帮助, 点击here

      【讨论】:

      • 您将如何使用这种方法为每个数据库处理自定义身份验证?
      【解决方案4】:

      springboot 2.3.3参考这里

      https://github.com/jose-m-thomas/mongo_multi_tenancy_spring_boot_2_3_3

      覆盖 doGetMongoDatabase 有助于实现多租户

          protected MongoDatabase doGetMongoDatabase(String dbName) {   
          }
      

      【讨论】:

        猜你喜欢
        • 2015-07-19
        • 2016-09-24
        • 2020-08-03
        • 1970-01-01
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多