Java 如何配置spring data mongodb以使用共享同一文档模型的两个不同mongo实例
我在一家拥有多个品牌的公司工作,因此我们在一些不同的主机上有几个MongoDB实例,每个品牌上都有相同的文档模型。(相同的结构,不同的数据) 为了简单起见,假设我们有一个橙色品牌,数据库实例服务于端口27017,香蕉品牌的数据库实例服务于端口27018 目前,我正在开发一项欺诈检测服务,该服务需要连接到所有数据库,并一起分析所有客户的行为,而不考虑品牌 因此,我的“模型”有一个共享的实体,用于客户,并用@Document注释(org.springframework.data.mongodb.core.mapping.Document) 下一件事是两个mongoresposition,例如:Java 如何配置spring data mongodb以使用共享同一文档模型的两个不同mongo实例,java,mongodb,spring-data-mongodb,Java,Mongodb,Spring Data Mongodb,我在一家拥有多个品牌的公司工作,因此我们在一些不同的主机上有几个MongoDB实例,每个品牌上都有相同的文档模型。(相同的结构,不同的数据) 为了简单起见,假设我们有一个橙色品牌,数据库实例服务于端口27017,香蕉品牌的数据库实例服务于端口27018 目前,我正在开发一项欺诈检测服务,该服务需要连接到所有数据库,并一起分析所有客户的行为,而不考虑品牌 因此,我的“模型”有一个共享的实体,用于客户,并用@Document注释(org.springframework.data.mongodb.co
public interface BananaRepository extends MongoRepository<Customer, String>
List<Customer> findAllByEmail(String email);
public interface OrangeRepository extends MongoRepository<Customer, String>
List<Customer> findAllByEmail(String email);
公共接口BananaRepository扩展了MongoRepository
列出FindAllByMail(字符串电子邮件);
公共接口OrangeRepository扩展了MongoRepository
列出FindAllByMail(字符串电子邮件);
使用一些存根方法通过Id、电子邮件等查找客户。Spring负责为此类接口生成所有实现类(相当标准的Spring内容)
为了提示每个存储库连接到正确的mongodb实例,我需要两个Mongo配置,例如:
@Configuration
@EnableMongoRepositories(basePackageClasses = {Customer.class})
public class BananaConfig extends AbstractMongoConfiguration {
@Value("${database.mongodb.banana.username:}")
private String username;
@Value("${database.mongodb.banana.database}")
private String database;
@Value("${database.mongodb.banana.password:}")
private String password;
@Value("${database.mongodb.banana.uri}")
private String mongoUri;
@Override
protected Collection<String> getMappingBasePackages() {
return Collections.singletonList("com.acme.model");
}
@Override
protected String getDatabaseName() {
return this.database;
}
@Override
@Bean(name="bananaClient")
public MongoClient mongoClient() {
final String authString;
//todo: Use MongoCredential
//todo: Use ServerAddress
//(See https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories) 10.3.4
if ( valueIsPresent(username) ||valueIsPresent(password)) {
authString = String.format("%s:%s@", username, password);
} else {
authString = "";
}
String conecctionString = "mongodb://" + authString + mongoUri + "/" + database;
System.out.println("Going to connect to: " + conecctionString);
return new MongoClient(new MongoClientURI(conecctionString, builder()
.connectTimeout(5000)
.socketTimeout(8000)
.readPreference(ReadPreference.secondaryPreferred())
.writeConcern(ACKNOWLEDGED)));
}
@Bean(name = "bananaTemplate")
public MongoTemplate mongoTemplate(@Qualifier("bananaFactory") MongoDbFactory mongoFactory) {
return new MongoTemplate(mongoFactory);
}
@Bean(name = "bananaFactory")
public MongoDbFactory mongoFactory() {
return new SimpleMongoDbFactory(mongoClient(),
getDatabaseName());
}
private static int sizeOfValue(String value){
if (value == null) return 0;
return value.length();
}
private static boolean valueIsMissing(String value){
return sizeOfValue(value) == 0;
}
private static boolean valueIsPresent(String value){
return ! valueIsMissing(value);
}
}
@配置
@EnableMongorPositories(basePackageClasses={Customer.class})
公共类BananaConfig扩展了AbstractMongoConfiguration{
@值(${database.mongodb.banana.username:})
私有字符串用户名;
@值(${database.mongodb.banana.database}”)
私有字符串数据库;
@值(${database.mongodb.banana.password:}”)
私有字符串密码;
@值(${database.mongodb.banana.uri})
蒙古里私人字符串;
@凌驾
受保护的集合getMappingBasePackages(){
returncollections.singletonList(“com.acme.model”);
}
@凌驾
受保护的字符串getDatabaseName(){
返回此数据库;
}
@凌驾
@Bean(name=“bananaClient”)
公共MongoClient MongoClient(){
最后一个字符串authString;
//todo:使用MongoCredential
//todo:使用服务器地址
//(见https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories) 10.3.4
if(valueIsPresent(用户名)| | valueIsPresent(密码)){
authString=String.format(“%s:%s@”,用户名,密码);
}否则{
authString=“”;
}
String conecctionString=“mongodb://”+authString+mongoUri+“/”+数据库;
System.out.println(“要连接到:“+conecctionString”);
返回新的MongoClient(新的MongoClientURI(conecctionString,builder())
.连接超时(5000)
.socketTimeout(8000)
.readPreference(readPreference.secondaryPreferred())
.writeConcern(已确认));
}
@Bean(name=“bananaTemplate”)
公共MongoTemplate MongoTemplate(@Qualifier(“bananaFactory”)MongoDB工厂mongoFactory){
返回新的MongoTemplate(mongoFactory);
}
@Bean(name=“bananaFactory”)
公共MongoDB工厂mongoFactory(){
返回新的SimpleMongoDbFactory(mongoClient(),
getDatabaseName());
}
私有静态int-sizeOfValue(字符串值){
if(value==null)返回0;
返回值.length();
}
私有静态布尔值丢失(字符串值){
返回sizeOfValue(value)==0;
}
私有静态布尔值Present(字符串值){
return!valueIsMissing(value);
}
}
I也有类似的橙色配置,指向正确的mongo实例
我的服务是这样的:
public List<? extends Customer> findAllByEmail(String email) {
return Stream.concat(
bananaRepository.findAllByEmail(email).stream(),
orangeRepository.findAllByEmail(email).stream())
.collect(Collectors.toList());
}
public List嗯,我有一个非常详细的答案,但是StackOverflow抱怨看起来像垃圾邮件,不允许我发布
完整的答案仍然可以作为
底线是,MongoRepository(接口)和模型对象必须放在同一个包中 更新:我发现了本文及其代码,尽管通过MongoProperties进行了不同的配置设置,但本文背后的关键概念是为每个配置提供单独的MongoTemplates,并将其连接起来,以便每个配置引用单独的模板。要记住一件重要的事情:模型和存储库都需要在同一个包中。否则它将不起作用,你将以误导性错误告终。因此,请引用上述文章:“为了能够创建多个MongoTemplate对象,有必要禁用mongodb的Spring引导自动配置。只需在application.properties文件中添加以下属性即可实现:spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.mongoutoconfiguration
(本文引用application.yml,因此我将该属性转换为applications.properties语法)