在同一应用程序中为同一模型和同一存储库使用多个 mongo 数据库

Use multiple mongo DBs in same application for same model & same Repository

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

例如我需要一些方法在我的存储库中创建 2 个 mongo 模板,例如 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(Class 或接口)或不同的模型。只想在单个回购中注入 2 个不同的 mongo 模板。

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

正如@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. 获取一个 class,这将有助于读取 mongo 数据库属性的自定义属性 application.properties:
@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. 添加配置 class 以创建 mongo 模板:
@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. 将以下减速添加到您的 service/repository:
    @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个副本集,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 标记为主要bean。如果没有模板被标记为主要,我还没有找到任何解决方案。
  • 如果任何 mongo 数据库已关闭且应用程序 started/restarted,应用程序将不会 start/deploy。为避免这种情况,需要将@Autowired 更改为@Autowired(required = false).
  • 如果任何 mongo 数据库已关闭且应用程序已经 运行,它会自动使用第二个 mongo BD(未关闭)。因此,即使您想使用 A DB,如果它已关闭,请求也会使用 B DB 处理,反之亦然。