MongoDb вставляет данные в разные БД на основе запроса SpringBoot Java - PullRequest
0 голосов
/ 13 декабря 2018

Model admin database structure Привет, у меня есть база данных mongoDb, которая содержит отдельные базы данных для разных магазинов, но коллекции внутри всех баз данных имеют одинаковую структуру, когда я получаю запрос от почтовой службы, я хочу вставить данныев соответствующую базу данных на основе идентификатора в запросе.Пожалуйста, посоветуйте, как это сделать в Springboot Java или Kotlin

AMAZON 
  - ProductDetails
FLIPKART
  - ProductDetails
EBAY
  - ProductDetails

Теперь у меня есть одна база данных, и я вставляю все детали продукта в одну базу данных, и я хочу добавить разные базы данных для разных магазинов

 spring.data.mongodb.host=mongo
 spring.data.mongodb.port=27017
 spring.data.mongodb.authentication-database=admin
 spring.data.mongodb.username=admin
 spring.data.mongodb.password=pass
 spring.data.mongodb.database=admin

1 Ответ

0 голосов
/ 16 декабря 2018

Поскольку вы новичок в Spring boot и MongoDB, я предоставлю вам следующие подробные инструкции по подключению нескольких БД mongo в одном приложении.Это один из самых простых способов настройки и подключения нескольких БД Монго.Надеюсь, это будет полезно (не забудьте проголосовать, если это так :-)) -

1) Структура пакета -

enter image description here

2) Создание абстрактного класса MongoDB Config -

package com.akash.mongo.multidb.config;

import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

/**
 * Abstract class for configuring different MongoTemplate for different DB
 * @author Akash
 *
 */
public abstract class AbstractMongoDbConfig {

    private String host;
    private String username;
    private String password;
    private String database;
    private int port;

    public void setHost(String host) {
        this.host = host;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setDatabase(String database) {
        this.database = database;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public MongoDbFactory mongoDbFactory() {

        MongoCredential mongoCredential = MongoCredential.createCredential(username, database, password.toCharArray());
        MongoClient mongoClient = new MongoClient(new ServerAddress(host, port), mongoCredential, new MongoClientOptions.Builder().build());

        return new SimpleMongoDbFactory(mongoClient, database);
    }

    public abstract MongoTemplate getMongoTemplate() throws Exception;

}

3) Расширение абстрактного класса для создания конфигурации для каждой БД

AmazonDbConfig

package com.akash.mongo.multidb.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * Configuration class for Amazon DB
 * @author Akash
 *
 */
@Configuration
@ConfigurationProperties(prefix="amazon.mongodb")
@EnableMongoRepositories(basePackages= {"com.akash.mongo.multidb.repository.amazon"}, mongoTemplateRef="amazonMongoTemplate")
public class AmazonDbConfig extends AbstractMongoDbConfig {

    private static final Logger logger = LoggerFactory.getLogger(AmazonDbConfig.class);

    @Override
    @Bean(name="amazonMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        logger.info("Creating MongoTemplate for Amazon DB");
        return new MongoTemplate(mongoDbFactory());
    }

}

EbayDbConfig

package com.akash.mongo.multidb.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * Configuration class for ebay DB
 * @author Akash
 *
 */
@Configuration
@ConfigurationProperties(prefix="ebay.mongodb")
@EnableMongoRepositories(basePackages= {"com.akash.mongo.multidb.repository.ebay"}, mongoTemplateRef="ebayMongoTemplate")
public class EbayDbConfig extends AbstractMongoDbConfig {

    private static final Logger logger = LoggerFactory.getLogger(EbayDbConfig.class);

    @Override
    @Bean(name="ebayMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        logger.info("Creating MongoTemplate for Ebay DB");
        return new MongoTemplate(mongoDbFactory());
    }

}

FlipkartDbConfig

package com.akash.mongo.multidb.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * Configuration class for Flipkart DB
 * @author Akash
 *
 */
@Configuration
@ConfigurationProperties(prefix="flipkart.mongodb")
@EnableMongoRepositories(basePackages= {"com.akash.mongo.multidb.repository.flipkart"}, mongoTemplateRef="flipkartMongoTemplate")
public class FlipkartDbConfig extends AbstractMongoDbConfig {

    private static final Logger logger = LoggerFactory.getLogger(FlipkartDbConfig.class);

    @Override
    @Primary
    @Bean(name="flipkartMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        logger.info("Creating MongoTemplate for Flipkart DB");
        return new MongoTemplate(mongoDbFactory());
    }

}

Обратите внимание, что каждый из этих классов конфигурации создает свой собственный MongoTemplateи это включает свой собственный MongoRepository.Также один из них должен быть @Primary, иначе пружинная загрузка выдаст ошибку.Неважно, какой из них является первичным;в конечном итоге они будут подключаться к своему собственному репозиторию

4) Создать сущности и репозиторий для каждой БД.

Теперь вам необходимо создать репозиторий для каждой БД.Учитывая, что ваша коллекция одинакова для всех БД, я создал следующий пример сущности -

package com.akash.mongo.multidb.entity;

import java.io.Serializable;

import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

/**
 * Sample Entity class
 * @author Akash
 *
 */
@Document(collection="productDetails")
public class ProductDetails implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private ObjectId id;

    @Field("productName")
    private String productName;

    @Field("productDesc")
    private String productDesc;

    @Field("productQuantity")
    private String productQuantity;

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductDesc() {
        return productDesc;
    }

    public void setProductDesc(String productDesc) {
        this.productDesc = productDesc;
    }

    public String getProductQuantity() {
        return productQuantity;
    }

    public void setProductQuantity(String productQuantity) {
        this.productQuantity = productQuantity;
    }

}

Вы можете создать / изменить класс сущности согласно сведениям о вашей коллекции.

AmazonRepository

package com.akash.mongo.multidb.repository.amazon;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.akash.mongo.multidb.entity.ProductDetails;

/**
 * 
 * @author Akash
 *
 */
@Repository
public interface AmazonRepository extends MongoRepository<ProductDetails, ObjectId> {

}

FlipkartRepository

package com.akash.mongo.multidb.repository.flipkart;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.akash.mongo.multidb.entity.ProductDetails;

@Repository
public interface FlipkartRepository extends MongoRepository<ProductDetails, ObjectId> {

}

EbayRepository

package com.akash.mongo.multidb.repository.ebay;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.akash.mongo.multidb.entity.ProductDetails;

/**
 * 
 * @author Akash
 *
 */
@Repository
public interface EbayRepository extends MongoRepository<ProductDetails, ObjectId> {

}

Опять же, каждый репозиторий должен быть своим собственным пакетом, иначе при запуске приложения будут возникать ошибки.Это один недостаток этого решения, когда вам нужно создать столько пакетов репозитория, сколько нет БД, которые вы хотите подключить.

5) Внедрение службы и подключение к различным репозиториям

Пакет интерфейса ProductDetailsService com.akash.mongo.multidb.service;

import com.akash.mongo.multidb.entity.ProductDetails;

/**
 * Sample interface with one add method
 * @author Akash
 *
 */
public interface ProductDetailsService {

    /**
     * 
     * @param productOrigin - the shop name i.e. Amazon, Flipkart or ebay.
     * @param productDetails - the product details to add
     */
    public void addProductDetails(String productOrigin, ProductDetails productDetails) throws RuntimeException;

}

ProductDetailsServiceImplКласс -

package com.akash.mongo.multidb.service;

import java.util.Map;

import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.repository.MongoRepository;

import com.akash.mongo.multidb.entity.ProductDetails;

/**
 * Implementation of ProductDetailsService interface
 * @author Akash
 *
 */
public class ProductDetailsServiceImpl implements ProductDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(ProductDetailsServiceImpl.class);

    /*
     * Spring boot will autowire all the repositories along with their name
     * amazonRepository - amazon repository instance
     * ebayRepository - ebay repository instance and so on
     */
    @Autowired
    Map<String, MongoRepository<ProductDetails, ObjectId>> repositories;

    @Override
    public void addProductDetails(String productOrigin, ProductDetails productDetails) throws RuntimeException {

        logger.info("Adding product details into {} db", productOrigin);

        //if productOrigin is Amazon; repositoryName will be amazonRepository which is already present in spring boot
        String repositoryName = productOrigin.toLowerCase()+"Repository";

        if(repositories.containsKey(repositoryName)) {
            repositories.get(repositoryName).save(productDetails);
        } else  {
            logger.error("{} shop is undefined in DB. Check and try again", productOrigin);
            throw new RuntimeException("Shop doesnot exist in MongoDb");
        }



    }

}

ProductOrigin Вы можете получить из вашего запроса или заголовков любую доступную вам информацию.

6) Наконец, application.properties

Изменение базы данных, имени пользователя и пароля для каждой БД.Старайтесь не использовать учетные данные администратора;Вместо этого создайте имя пользователя и пароль для каждой БД отдельно и обновите application.properties.

#MongoDb connection properties for Flipkart DB
flipkart.mongodb.database=flipkart
flipkart.mongodb.host=http://127.0.0.1
flipkart.mongodb.port=27017
flipkart.mongodb.username=flipkart
flipkart.mongodb.password=flipkart

#MongoDb connection properties for Amazon DB
amazon.mongodb.database=amazon
amazon.mongodb.host=http://127.0.0.1
amazon.mongodb.port=27017
amazon.mongodb.username=amazon
amazon.mongodb.password=amazon

#MongoDb connection properties for ebay DB
ebay.mongodb.database=ebay
ebay.mongodb.host=http://127.0.0.1
ebay.mongodb.port=27017
ebay.mongodb.username=ebay
ebay.mongodb.password=ebay

Теперь, если вам нужно добавить любую новую базу данных, вам просто нужно добавить один класс конфигурации, похожий на AmazonDbConfig, еще один пакет с необходимыми репозиториями для этой БД и сведениями о соединении в application.properties.Никаких изменений в обслуживании не требуется, пока ваша коллекция не станет одинаковой для всех БД.

Если у вас есть несколько коллекций, вы можете добавить сущность и репозиторий для каждой коллекции (сгруппировать все репозитории для одного магазина в одну упаковку) ирешение должно оставаться в силе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...