Используйте несколько баз данных mongo в одном приложении для одной модели и одного репозитория.

Мне нужно реализовать приложение Spring boot — MongoDb, в котором есть 2 базы данных mongo с одинаковыми именами и коллекциями базы данных. В зависимости от того, как пользователь делает запрос, мне нужно выбрать, следует ли извлекать данные из 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 отдельных репо (класс или интерфейс) или разные модели. Просто хочу, чтобы 2 разных mongoTemplates были введены в одно репо.

Это возможно? Если да, то приведите пример кода. Я следовал приведенному ниже руководству: https://dzone.com/articles/multiple-mongodb-connectors-with-spring-boot


person Saurabhcdt    schedule 24.09.2019    source источник
comment
Я считаю, что есть два способа сделать это, один из которых вы уже показали, то есть использовать свой собственный класс репозитория и реализовать все методы CRUD, которые вам нужны, используя вашу логику для использования шаблонов. Второй способ — использовать, аспекты, а затем перехватывать все методы репозитория с помощью @Before и затем изменять mongoTemplateRef в зависимости от вашей логики.   -  person Lucia    schedule 30.09.2019
comment
@Lucia То, как я показал, - это то, что я хочу, но не реализовал. Нужно знать, как инициализировать 2 шаблона в 1 репозитории с разными источниками. Либо для этого, либо для того, как вы упомянули, не могли бы вы помочь с каким-либо примером кода? Я новичок в весенней загрузке и не могу понять, как мне это реализовать.   -  person Saurabhcdt    schedule 01.10.2019
comment
вы можете перейти по ссылке ниже, чтобы понять, что blog.marcosbarbero.com/ В приведенной выше ссылке вы выполняете шаги, пока не создадите класс конфигурации MultipleMongoConfig, в котором он определяет два bean-компонента: primaryMongoTemplate иsecondaryMongoTemplate. вы можете автоматически связать их в своем классе репозитория, как вы это сделали в вопросе, который вы написали. Просто добавьте @Qualifier(primaryMOngoTemplate) и @Qualifier(secondaryMongoTemplate)   -  person Lucia    schedule 01.10.2019


Ответы (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. Получите один класс, который поможет в чтении пользовательских свойств для свойств mongo db в 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. Добавьте класс конфигурации для создания 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, один компонент должен быть помечен как основной. Я не нашел никакого решения, если ни один шаблон не помечен как основной.
  • Если какая-либо из баз данных mongo не работает и приложение запущено/перезапущено, приложение не запустится/развернется. чтобы избежать этого, @Autowired нужно изменить на @Autowired(required = false).
  • Если какая-либо из баз данных mongo не работает, а приложение уже запущено, оно автоматически использует второй BD mongo (который не отключен). Таким образом, даже если вы хотите использовать базу данных A, если она не работает, запросы обрабатываются с помощью базы данных B и наоборот.
person Saurabhcdt    schedule 25.10.2019