此版本仍在开发中,尚未被视为稳定版。如需最新稳定版本,请使用 Spring Data MongoDB 5.0.4spring-doc.cadn.net.cn

模板 API

The MongoTemplate 及其位于 org.springframework.data.mongodb.core 包中的 响应式 对应类,是 Spring MongoDB 支持的核心类,提供了丰富的功能集用于与数据库交互。 该模板提供了便捷的创建、更新、删除和查询 MongoDB 文档的操作,并实现了您的领域对象与 MongoDB 文档之间的映射。spring-doc.cadn.net.cn

一旦配置完成,MongoTemplate 就是线程安全的,可以在多个实例之间重复使用。

便利方法

MongoTemplate 实现了接口 MongoOperations。 在可能的情况下,MongoOperations 上的方法命名与 MongoDB 驱动程序 Collection 对象中可用的方法保持一致,以便让熟悉驱动程序 API 的现有 MongoDB 开发者能够轻松上手。 例如,您可以找到诸如 findfindAndModifyfindAndReplacefindOneinsertremovesaveupdateupdateMulti 等方法。 设计目标是尽可能简化从基础 MongoDB 驱动程序过渡到 MongoOperations 的过程。 这两种 API 之间的一个主要区别是,MongoOperations 可以传递领域对象,而不是 Document。 此外,MongoOperations 提供了针对 QueryCriteriaUpdate 操作的流式 API,而不需要填充 Document 来指定这些操作的参数。spring-doc.cadn.net.cn

如需更多信息,请参阅文档中的CRUD查询部分。spring-doc.cadn.net.cn

引用 MongoTemplate 实例上的操作的首选方式是通过其接口 MongoOperations

执行回调

MongoTemplate 提供了许多便捷方法,帮助您轻松执行常见任务。 然而,如果您需要直接访问 MongoDB 驱动程序 API,可以使用多个 Execute 回调方法之一。 这些 execute 回调方法会为您提供对 MongoCollectionMongoDatabase 对象的引用。spring-doc.cadn.net.cn

  • <T> T execute (Class<?> entityClass, CollectionCallback<T> action):为指定类的实体集合执行给定的 CollectionCallbackspring-doc.cadn.net.cn

  • <T> T execute (String collectionName, CollectionCallback<T> action):在指定名称的集合上执行给定的 CollectionCallbackspring-doc.cadn.net.cn

  • <T> T execute (DbCallback<T> action):执行一个 DbCallback,并在必要时转换任何异常。 Spring Data MongoDB 提供了对 MongoDB 2.2 版本中引入的聚合框架(Aggregation Framework)的支持。spring-doc.cadn.net.cn

  • <T> T execute (String collectionName, DbCallback<T> action):在指定名称的集合上执行一个 DbCallback,并根据需要转换任何异常。spring-doc.cadn.net.cn

  • <T> T executeInSession (DbCallback<T> action):在同一个数据库连接中执行给定的 DbCallback,以确保在写入密集型环境中读取到刚刚写入的数据,从而保证一致性。spring-doc.cadn.net.cn

以下示例使用 CollectionCallback 返回有关索引的信息:spring-doc.cadn.net.cn

boolean hasIndex = template.execute("geolocation", collection ->
    Streamable.of(collection.listIndexes(org.bson.Document.class))
        .stream()
        .map(document -> document.get("name"))
        .anyMatch("location_2d"::equals)
);
Mono<Boolean> hasIndex = template.execute("geolocation", collection ->
    Flux.from(collection.listIndexes(org.bson.Document.class))
        .map(document -> document.get("name"))
        .filterWhen(name -> Mono.just("location_2d".equals(name)))
        .map(it -> Boolean.TRUE)
        .single(Boolean.FALSE)
    ).next();

流畅 API

作为与 MongoDB 进行更底层交互时的核心组件,MongoTemplate 提供了丰富多样的方法,涵盖从集合创建、索引创建和 CRUD 操作,到更高级的功能(如 Map-Reduce 和聚合操作)的各种需求。 每个方法都有多个重载版本, 其中大多数用于处理 API 中可选或可为空的部分。spring-doc.cadn.net.cn

FluentMongoOperations 提供了一个更为精简的接口,涵盖了 MongoOperations 的常用方法,并提供了一种更具可读性的流畅 API。 其入口点(insert(…)find(…)update(…) 等)采用基于所要执行操作的自然命名方案。 从入口点开始,该 API 的设计仅提供与上下文相关的方法,最终导向一个终止方法,该方法会调用实际对应的 MongoOperations 方法——在以下示例中即为 all 方法:spring-doc.cadn.net.cn

命令式
List<Jedi> all = template.query(SWCharacter.class) (1)
  .inCollection("star-wars") (2)
  .as(Jedi.class) (3)
  .matching(query(where("jedi").is(true))) (4)
  .all();
1 用于映射查询中所用字段的目标类型。
2 如果在领域类型上未定义,则使用的集合名称。
3 如果不使用原始领域类型时的结果类型。
4 查找查询。
响应式
Flux<Jedi> all = template.query(SWCharacter.class)
  .inCollection("star-wars")
  .as(Jedi.class)
  .matching(query(where("jedi").is(true)))
  .all();
使用投影允许 MongoTemplate 通过限制实际响应为投影目标类型所需的字段来优化结果映射。 只要 Query 本身不包含任何字段限制,且目标类型为封闭接口或 DTO 投影,此规则即适用。
投影不得应用于 DBRefs

你可以通过终止方法 ListStreamfirst()one() 在检索单个实体与以 all()stream() 形式检索多个实体之间进行切换。spring-doc.cadn.net.cn

在使用 near(NearQuery) 编写地理空间查询时,可用的终止方法数量会发生变化,仅包含那些在 MongoDB 中执行 geoNear 命令时有效的方法(以 GeoResult 形式返回实体,并封装为 GeoResults),如下例所示:spring-doc.cadn.net.cn

GeoResults<Jedi> results = template.query(SWCharacter.class)
  .as(Jedi.class)
  .near(alderaan) // NearQuery.near(-73.9667, 40.78).maxDis…
  .all();
Flux<GeoResult<Jedi>> results = template.query(SWCharacter.class)
  .as(Jedi.class)
  .near(alderaan) // NearQuery.near(-73.9667, 40.78).maxDis…
  .all();

异常转换

Spring 框架为各种数据库和映射技术提供了异常转换功能。 传统上,这适用于 JDBC 和 JPA。 Spring 对 MongoDB 的支持通过提供 org.springframework.dao.support.PersistenceExceptionTranslator 接口的实现,将此功能扩展到了 MongoDB 数据库。spring-doc.cadn.net.cn

将异常映射到 Spring 的一致的数据访问异常体系背后的动机在于,这样你就可以编写可移植且具有描述性的异常处理代码,而无需直接针对 MongoDB 错误码进行编码。 Spring 所有的数据访问异常都继承自根类 DataAccessException,因此你可以确保在单个 try-catch 代码块中捕获所有与数据库相关的异常。 请注意,并非 MongoDB 驱动抛出的所有异常都继承自 MongoException 类。 内部异常和消息会被保留,因此不会丢失任何信息。spring-doc.cadn.net.cn

MongoExceptionTranslator 执行的部分映射包括将 com.mongodb.Network 映射到 DataAccessResourceFailureException,以及将错误代码 1003、12001、12010、12011 和 12012 从 MongoException 映射到 InvalidDataAccessApiUsageException。 如需了解映射的更多详细信息,请查看具体实现。spring-doc.cadn.net.cn

异常转换可以通过在您的 MongoExceptionTranslator 或其响应式变体上设置自定义配置来完成。 您可能还需要在相应的 MongoClientFactoryBean 上设置异常转换器。spring-doc.cadn.net.cn

示例 1. 配置 MongoExceptionTranslator
ConnectionString uri = new ConnectionString("mongodb://username:password@localhost/database");
SimpleMongoClientDatabaseFactory mongoDbFactory = new SimpleMongoClientDatabaseFactory(uri);
mongoDbFactory.setExceptionTranslator(myCustomExceptionTranslator);

自定义异常的一个动机源于 MongoDB 在事务处理中的行为:某些失败(例如写冲突)可能是暂时性的,重试操作可能会成功。 在这种情况下,您可以使用特定的 MongoDB 标签包装异常,并应用不同的异常转换策略。spring-doc.cadn.net.cn

域类型映射

MongoDB 文档与领域类之间的映射是通过委托给 MongoConverter 接口的实现来完成的。 Spring 提供了 MappingMongoConverter,但您也可以编写自己的转换器。 虽然 MappingMongoConverter 可以使用额外的元数据来指定对象到文档的映射,但它也可以利用 ID 和集合名称映射的一些约定,转换不包含任何额外元数据的对象。 这些约定以及映射注解的使用,将在 映射 章节中进行说明。spring-doc.cadn.net.cn