MongoDb根据请求SpringBoot Java将数据插入不同的DB

时间:2018-12-13 05:13:37

标签: java mongodb spring-boot kotlin

Model admin database structure嗨,我有mongoDb数据库,其中包含用于不同商店的单独数据库,但是所有数据库中的集合都具有相同的结构,当我从邮政服务获得请求时,我想将数据插入到相应的数据库中根据请求中的ID。请建议如何在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 :(得分:1)

由于您是Spring Boot和MongoDB的新手,我为您提供了以下详细步骤,以在单个应用程序中连接多个mongo DB。这是配置和连接多个mongo DB的最简单方法之一。希望这会有所帮助(如果是,请不要忘记投票:))-

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> {

}

Flipkart存储库

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)服务实施并连接到不同的存储库

ProductDetailsS​​ervice接口     包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;

}

ProductDetailsS​​erviceImpl类-

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中的连接详细信息。在所有数据库的收集相同之前,无需更改服务。

如果您有多个馆藏,则可以为每个馆藏添加实体和存储库(将单个商店的所有存储库分组在一个包装中),并且解决方案仍然适用。