【问题标题】:Use multiple mongo DBs in same application for same model & same Repository在同一应用程序中为同一模型和同一存储库使用多个 mongo DB
【发布时间】:2019-09-24 14:33:22
【问题描述】:

我需要实现 Spring boot - MongoDb 应用程序,其中有 2 个具有完全相同的数据库名称和集合的 mongo DB。根据用户发出的请求,我需要选择是从 DB1 还是 DB2 获取数据(只有 mongo URI 主机 - IP 不同)。

例如我需要一些方法在我的存储库中创建 2 个 mongoTemplates,例如 mTempA 和 mTempB,并根据某些条件,使用任一模板执行查询,如下所示:

@Repository
public class MyCustomRepository {

private Logger logger = LoggerFactory.getLogger(MyCustomRepository.class);

@Autowired
private MongoTemplateA mongoTemplateA;// Need to know if this is possible & how

@Autowired
private MongoTemplateB mongoTemplateB;// Need to know if this is possible & how

public List<MyModel> findByCriteria(MyRequest request) {
    List<MyModel> result;
    //Query query = <build query based on request>

    if (request.getUserType().equals("A")) {
        result = mongoTemplateA.find(query, MyModel.class);
    } else {
        result = mongoTemplateB.find(query, MyModel.class);
    }

    logger.debug("Result fetched with {} records", result.size());
    return result;
}   
}

我不想使用 2 个单独的 Repo(类或接口)或不同的模型。只想在单个仓库中注入 2 个不同的 mongoTemplates。

这可能吗?如果是,请给出一些示例代码。 我遵循了以下教程: https://dzone.com/articles/multiple-mongodb-connectors-with-spring-boot

【问题讨论】:

  • 我相信有两种方法可以做到这一点,一种是您已经展示过的,即使用您自己的存储库类并使用您的模板使用逻辑实现您需要的所有 CRUD 方法。第二种方法是使用方面,然后使用 @Before 捕获存储库的所有方法,然后根据您的逻辑更改 mongoTemplateRef。
  • @Lucia 我展示的方式是我想要但没有实现的。需要知道如何用不同的来源初始化 1 个存储库中的 2 个模板。无论是这个还是你提到的方式,你能帮忙提供任何示例代码吗?我是 Spring Boot 新手,不知道应该如何实现它。
  • 您可以通过以下链接了解blog.marcosbarbero.com/… 在上面的链接中,您将通过步骤直到创建配置类“MultipleMongoConfig”,其中他定义了两个bean“primaryMongoTemplate”和“secondaryMongoTemplate” .你可以在你的 Repository 类中自动装配它们,就像你在你写的问题中所做的那样。只需添加 @Qualifier("primaryMONgoTemplate") 和 @Qualifier("secondaryMongoTemplate")

标签: mongodb spring-boot spring-data-mongodb mongotemplate


【解决方案1】:

正如@Lucia 正确指出的那样,以下是如何做到的:

  1. 有 2 个不同的配置占位符
@Configuration
@EnableMongoRepositories(basePackages = "com.snk.repository", mongoTemplateRef = "mongoTemplateA")
public class MongoConfigA {
    // Configuration class for DB 1 access
}

@Configuration
@EnableMongoRepositories(basePackages = "com.snk.repository", mongoTemplateRef = "mongoTemplateB")
public class MongoConfigB {
    // Configuration class for DB 2 access
}
  1. 获取一个有助于在 application.properties 中读取 mongo db 属性的自定义属性的类:
@ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {

    private MongoProperties adb = new MongoProperties();
    private MongoProperties bdb = new MongoProperties();

    public MongoProperties getAdb() {
        return adb;
    }

    public MongoProperties getBdb() {
        return bdb;
    }
}
  1. 添加配置类以创建 mongoTemplates:
@Configuration
@EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {

    @Autowired
    private MultipleMongoProperties mongoProperties = new MultipleMongoProperties();

    @Bean(name = "mongoTemplateA")
    @Primary
    public MongoTemplate mongoTemplateA() {
        return new MongoTemplate(aDbFactory(this.mongoProperties.getAdb()));
    }

    @Bean(name = "mongoTemplateB")
    public MongoTemplate mongoTemplateB() {
        return new MongoTemplate(bDbFactory(this.mongoProperties.getBdb()));
    }

    @Bean
    @Primary
    public MongoDbFactory aDbFactory(final MongoProperties mongo) {
        return new SimpleMongoDbFactory(new MongoClientURI(mongo.getUri()));
    }

    @Bean
    public MongoDbFactory bDbFactory(final MongoProperties mongo) {
        return new SimpleMongoDbFactory(new MongoClientURI(mongo.getUri()));
    }
}
  1. 将以下减速添加到您的服务/存储库:
    @Autowired
    @Qualifier("mongoTemplateA")
    private MongoTemplate mongoTemplateA;

    @Autowired
    @Qualifier("MongoTemplateB")
    private MongoTemplate MongoTemplateB;
  1. 在您的 application.properties 中添加以下属性:
mongodb.adb.uri=mongodb://user:pass@myhost1:27017/adb
mongodb.bdb.uri=mongodb://user:pass@myhost2:27017/bdb

如果你设置了mongo rplica,URL可以设置为:

mongodb.adb.uri=mongodb://user:pass@myhost1,myhost2,myhost13/adb?replicaSet=rsName
mongodb.bdb.uri=mongodb://user:pass@myhost1,myhost2,myhost13/bdb?replicaSet=rsName

根据您的逻辑,使用任一模板。 想了想,有几个问题:

  • 注意@Primary 注释,需要将一个bean 标记为主要的。如果没有模板被标记为主要,我还没有找到任何解决方案。
  • 如果任何 mongo DB 已关闭并且应用程序已启动/重新启动,应用程序将不会启动/部署。为避免这种情况,需要将 @Autowired 更改为 @Autowired(required = false)。
  • 如果任何 mongo DB 已关闭且应用程序已在运行,它会自动使用第二个 mongo BD(未关闭)。因此,即使您想使用 A DB,如果它出现故障,请求也会使用 B DB 处理,反之亦然。

【讨论】:

    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2011-08-04
    • 2013-04-22
    • 2014-01-08
    • 2017-12-01
    • 1970-01-01
    相关资源
    最近更新 更多