Поскольку вы новичок в Spring boot и MongoDB, я предоставлю вам следующие подробные инструкции по подключению нескольких БД mongo в одном приложении.Это один из самых простых способов настройки и подключения нескольких БД Монго.Надеюсь, это будет полезно (не забудьте проголосовать, если это так :-)) -
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;
}
}
Вы можете создать / изменить класс сущности согласно сведениям о вашей коллекции.
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.Никаких изменений в обслуживании не требуется, пока ваша коллекция не станет одинаковой для всех БД.
Если у вас есть несколько коллекций, вы можете добавить сущность и репозиторий для каждой коллекции (сгруппировать все репозитории для одного магазина в одну упаковку) ирешение должно оставаться в силе.