gpt4 book ai didi

spring - 可以将 Spring Data MongoDB 配置为支持每个存储库的不同数据库吗?

转载 作者:可可西里 更新时间:2023-11-01 09:57:47 28 4
gpt4 key购买 nike

过去一周我一直在努力将 Spring Data MongoDB 成功集成到我们的应用程序中。我们使用相当普遍的做法,为我们依赖的每个集合使用单独的数据库。例如,TenantConfiguration 数据库仅包含 TenantConfigurations 集合。

我已多次通读文档并搜索解决方案的代码,但一无所获。这样一个广泛采用的项目肯定可以解决这个问题吗?我目前的尝试是这样的:

@Configuration
@EnableMongoRepositories(basePackages = "com.whatever.service.repository",
basePackageClasses = TenantConfigurationRepository.class,
mongoTemplateRef = "tenantConfigurationTemplate")
public class TenantConfigurationRepositoryConfig {

@Value("${mongo.hosts}")
private List<String> mongoHosts;

@Bean
public MongoTemplate tenantConfigurationTemplate() throws Exception {
final List<ServerAddress> serverAddresses = new ArrayList<>();
for (String host : mongoHosts) {
serverAddresses.add(new ServerAddress(host, 27017));
}

final MongoClientOptions clientOptions = new MongoClientOptions.Builder()
.connectTimeout(25000)
.readPreference(ReadPreference.primaryPreferred())
.build();

final MongoClient client = new MongoClient(serverAddresses, clientOptions);
return new MongoTemplate(client, "TenantConfiguration");
}
}

这是其他单个存储库配置之一:

@Configuration
@EnableMongoRepositories(basePackages = "com.whatever.service.repository",
basePackageClasses = RegisteredCardRepository.class,
mongoTemplateRef = "registeredCardTemplate")
public class RegisteredCardRepositoryConfig {

@Value("${mongo.hosts}")
private List<String> mongoHosts;

@Bean
public MongoTemplate registeredCardTemplate() throws Exception {
final List<ServerAddress> serverAddresses = new ArrayList<>();
for (String host : mongoHosts) {
serverAddresses.add(new ServerAddress(host, 27017));
}

final MongoClientOptions clientOptions = new MongoClientOptions.Builder()
.connectTimeout(25000)
.readPreference(ReadPreference.primaryPreferred())
.build();

final MongoClient client = new MongoClient(serverAddresses, clientOptions);
return new MongoTemplate(client, "RegisteredCard");
}
}

现在这是 RegisteredCard 存储库的实际存储库定义:

@Repository
public interface RegisteredCardRepository extends MongoRepository<RegisteredCard, Guid>,
QueryDslPredicateExecutor<RegisteredCard> { }

这一切对我来说都非常有意义,各个配置唯一地标识了它们配置的特定存储库接口(interface)和特定模板bean以通过mongoTemplateRef 注释的参数。至少,文档似乎暗示它应该如此工作。

实际上,当我启动应用程序时,RegisteredCard 存储库解析为一个 MongoDB 存储库实例,该实例具有绑定(bind)到 TenantConfiguration 数据库的关联 MongoDbFactory。事实上,每个存储库都会收到相同的、不正确的 MongoOperations 对象。尽管每个存储库都有自己独特的配置,但似乎首先访问的数据库仍然是每个存储库的目标数据库。

这个问题有什么解决方案吗?

最佳答案

我花了将近一周的时间,但实际上我找到了解决这个问题的可行方法。以下是我在研究此问题时收集到的事实的简要概述:

  • @EnableMongoRepositories(basePackageClasses = Whatever.class) 只是使用限定的类名来指示它应该为 所有 扫描什么定义的数据模型。如果 Whatever.class 驻留在该包中,这完全等同于执行 @EnableMongoRepositories(basePackageClasses = "com.mypackage.whatevers")
  • @EnableMongoRepositories 不可重复,但可用于注释多个类。这已在其他 SO 对话中进行了介绍,但值得在此重复。您将需要定义几个 存储库配置类; 一个用于您打算与之交互的每个数据库
  • 您的每个单独的存储库配置都必须在 @EnableMongoRepositories 注释中指定其自己的 MongoTemplate 实例。您可以只提供一个 Mongo bean,但 MongoTemplate 依赖于特定的 MongoMappingContext
  • @EnableMongoRepositories 注释有助于定义您的映射上下文,它了解您的数据模型的结构以及如何序列化它们。它还理解 @Document@Field 注释,并执行持久化对象的繁重工作。 Mongo 模板实例是您指定要与之交互的数据库的地方。因此,通过为 @EnableMongoRepositories 注释提供 basePackage 属性和 mongoTemplateRef 属性,您可以告诉 Spring Data Mongo“采用这些模型并持久化他们在这个特定的数据库中”。

此解决方案的不幸要求是您必须根据它们所属的数据库将数据模型组织到单独的包中。如果像我一样,您正在使用 Mongo 数据库结构,该结构为每个数据库分配一个集合(这对于频繁访问的集合来说是相当常见的),这意味着您的每个数据模型都必须驻留在自己的包中。这些包中的每一个都必须由 @EnableMongoRepositories 注释指向,该注释还包含指向唯一 MongoTemplate bean 的 mongoTemplateRef 属性。

我希望这可以帮助其他人避免我在尝试完成应该是相当普通的 Mongo 集成时遇到的麻烦。

PS:放弃所有希望,那些试图将审计与此配置相结合的人。

关于spring - 可以将 Spring Data MongoDB 配置为支持每个存储库的不同数据库吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38086267/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com