【问题标题】:MongoDb insert data to different DBs based on request SpringBoot JavaMongoDb根据请求SpringBoot Java将数据插入不同的DB
【发布时间】:2019-05-14 06:51:02
【问题描述】:

嗨我有 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

【问题讨论】:

  • @Mohanraj 至少有一种方法是检查集合是否存在。如果没有,请使用商店名称创建一个新系列。根据您的属性,我假设您现在想这样做 - DB - 商店,DB 中的集合 - 亚马逊、Flipkart、Ebay、Myntra 等,内部集合,您可以为给定的请求 ID 创建或更新文档(应与集合相同)。
  • 在需要之前不要创建/更改数据库。将所有类似的集合保存在一个数据库中。在您的情况下,可能也不需要为每个单独的集合。创建以商店名称(例如 Amazon、Flipkart)和产品名称为关键的文档,您将避免很多复杂性。
  • 我将在几分钟内尝试发布这两种方法的示例代码。你可以检查一下。
  • @Mohanraj github.com/Loki-Afro/multi-tenant-spring-mongodb 看看这个。它很旧,但可能会有所帮助。它看起来完全符合您的要求。
  • 没问题!我会尽力为您提供答案的起点。

标签: java mongodb spring-boot kotlin


【解决方案1】:

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

1) 包结构-

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;
    }

}

您可以根据您的收藏详情创建/修改实体类。

亚马逊仓库

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

}

易趣存储库

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

如果您有多个集合,您可以为每个集合添加实体和存储库(将单个商店的所有存储库组合在一个包中)并且解决方案应该仍然有效。

【讨论】:

  • 没问题! :-)
猜你喜欢
  • 2017-11-08
  • 2019-07-21
  • 2016-05-07
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-02
  • 1970-01-01
相关资源
最近更新 更多