Template API

  • 创建、更新、删除和查询 MongoDB 文档,并提供域对象与 MongoDB 文档之间的映射。

  • 访问 MongoDB 驱动器 API,通过 Execute 回调执行高级任务。

  • 支持 MongoDB 聚合框架,用于执行复杂的查询和数据聚合。

  • 提供 Fluent API,支持更具可读性和可控性的 MongoDB交互。

  • 提供异常翻译,将 MongoDB 特定的异常映射到 Spring 的一致的数据访问异常层次结构。

  • 通过 MongoConverter 接口实现 MongoDB 文档与域类的映射。

位于 org.springframework.data.mongodb.core 包中的 MongoTemplate 及其响应式对应类是 Spring 的 MongoDB 支持的中心类,并提供了一组丰富的功能用于与数据库交互。该模板提供了便利的操作,用于创建、更新、删除和查询 MongoDB 文档,并在您的域对象和 MongoDB 文档之间提供了一个映射。

The MongoTemplate and its reactive counterpart class, located in the org.springframework.data.mongodb.core package, is the central class of Spring’s MongoDB support and provides a rich feature set for interacting with the database. The template offers convenience operations to create, update, delete, and query MongoDB documents and provides a mapping between your domain objects and MongoDB documents.

一旦配置,MongoTemplate 就是线程安全的,并且可以在多个实例中重复使用。

Once configured, MongoTemplate is thread-safe and can be reused across multiple instances.

Convenience Methods

MongoTemplate 类实现了 MongoOperations 接口。尽可能让 MongoOperation 上的方法以 MongoDB 驱动器 Collection 对象上可用方法命名,使对习惯使用驱动器 API 的现有的 MongoDB 开发人员而言这个 API 显得较为熟悉。例如,您可以找到诸如 findfindAndModifyfindAndReplacefindOneinsertremovesaveupdateupdateMulti 等方法。设计目标是尽可能轻松地实现 MongoDB 基本驱动器和 MongoOperations 之间的转换。两个 API 之间的主要区别在于 MongoOperations 可以传递域对象而不是 Document。此外,MongoOperations 具有用于 QueryCriteriaUpdate 操作的流畅 API,而不是填充 Document 以指定这些操作的参数。

The MongoTemplate class implements the interface MongoOperations. In as much as possible, the methods on MongoOperations are named after methods available on the MongoDB driver Collection object, to make the API familiar to existing MongoDB developers who are used to the driver API. For example, you can find methods such as find, findAndModify, findAndReplace, findOne, insert, remove, save, update, and updateMulti. The design goal was to make it as easy as possible to transition between the use of the base MongoDB driver and MongoOperations. A major difference between the two APIs is that MongoOperations can be passed domain objects instead of Document. Also, MongoOperations has fluent APIs for Query, Criteria, and Update operations instead of populating a Document to specify the parameters for those operations.

有关更多信息,请参阅文档的 CRUDQuery 部分。

For more information please refer to the the CRUD and Query sections of the documentation.

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

The preferred way to reference the operations on MongoTemplate instance is through its interface, MongoOperations.

Execute Callbacks

MongoTemplate 提供了很多便利方法,可帮助您轻松地执行常见任务。但是,如果您需要直接访问 MongoDB 驱动器的 API,您可以使用几个 Execute 回调方法中的一个。execute 回调为您提供 MongoCollectionMongoDatabase 对象的引用。

MongoTemplate offers many convenience methods to help you easily perform common tasks. However, if you need to directly access the MongoDB driver API, you can use one of several Execute callback methods. The execute callbacks gives you a reference to either a MongoCollection or a MongoDatabase object.

  • <T> T execute (Class<?> entityClass, CollectionCallback<T> action): Runs the given CollectionCallback for the entity collection of the specified class.

  • <T> T execute (String collectionName, CollectionCallback<T> action): Runs the given CollectionCallback on the collection of the given name.

  • <T> T execute (DbCallback<T> action): Runs a DbCallback, translating any exceptions as necessary. Spring Data MongoDB provides support for the Aggregation Framework introduced to MongoDB in version 2.2.

  • <T> T execute (String collectionName, DbCallback<T> action): Runs a DbCallback on the collection of the given name translating any exceptions as necessary.

  • <T> T executeInSession (DbCallback<T> action): Runs the given DbCallback within the same connection to the database so as to ensure consistency in a write-heavy environment where you may read the data that you wrote.

以下示例使用 CollectionCallback 返回有关索引的信息:

The following example uses the CollectionCallback to return information about an index:

boolean hasIndex = template.execute("geolocation", collection ->
    Streamable.of(collection.listIndexes(org.bson.Document.class))
        .stream()
        .map(document -> document.get("name"))
        .anyMatch("location_2d"::equals)
);

Fluent API

当涉及到与 MongoDB 的更底层交互时,作为中心组件的 MongoTemplate 提供了各种方法,涵盖了广泛的需求,从集合创建、索引创建和 CRUD 操作到更高级的功能,如 Map-Reduce 和聚合。您可以找到每个方法的多个重载。它们中的大多数涵盖了 API 中可选或可为空的部分。

Being the central component when it comes to more low-level interaction with MongoDB MongoTemplate offers a wide range of methods covering needs from collection creation, index creation, and CRUD operations to more advanced functionality, such as Map-Reduce and aggregations. You can find multiple overloads for each method. Most of them cover optional or nullable parts of the API.

FluentMongoOperationsMongoOperations 的常见方法提供了一个更狭窄的接口,并提供了一个可读性更强、更流畅的 API。入口点(insert(…​)find(…​)update(…​) 等)遵循一个基于运行操作的自然命名模式。从入口点开始,API 被设计为仅提供导致终止方法(在以下示例中为 all 方法)的上下文相关方法,该终止方法调用实际的 MongoOperations 对应部分:

FluentMongoOperations provides a more narrow interface for the common methods of MongoOperations and provides a more readable, fluent API. The entry points (insert(…), find(…), update(…), and others) follow a natural naming schema based on the operation to be run. Moving on from the entry point, the API is designed to offer only context-dependent methods that lead to a terminating method that invokes the actual MongoOperations counterpart — the all method in the case of the following example:

Imperative
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 The type used to map fields used in the query to.
2 The collection name to use if not defined on the domain type.
3 Result type if not using the original domain type.
4 The lookup query.
Reactive
Flux<Jedi> all = template.query(SWCharacter.class)
  .inCollection("star-wars")
  .as(Jedi.class)
  .matching(query(where("jedi").is(true)))
  .all();

使用投影允许 MongoTemplate 通过将实际响应限制为投影目标类型所需的字段来优化结果映射。只要 Query 本身不包含任何字段限制,并且目标类型是闭合接口或 DTO 投影,这一特性都适用。

Using projections allows MongoTemplate to optimize result mapping by limiting the actual response to fields required by the projection target type. This applies as long as the Query itself does not contain any field restriction and the target type is a closed interface or DTO projection.

必须不将映射应用于DBRefs

Projections must not be applied to DBRefs.

您可以通过终止方法:first()one()all()stream(),在检索一个实体和将多个实体检索为 ListStream 之间进行切换。

You can switch between retrieving a single entity and retrieving multiple entities as a List or a Stream through the terminating methods: first(), one(), all(), or stream().

使用 near(NearQuery) 编写地理空间查询时,终止方法的数量会发生更改,以仅包括对在 MongoDB 中运行 geoNear 命令有效的方法(在 GeoResults 中将实体获取为 GeoResult),如下例所示:

When writing a geo-spatial query with near(NearQuery), the number of terminating methods is altered to include only the methods that are valid for running a geoNear command in MongoDB (fetching entities as a GeoResult within GeoResults), as the following example shows:

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

Exception Translation

Spring 框架为各种各样的数据库和映射技术提供了异常翻译。传统上,这是针对 JDBC 和 JPA 的。Spring 对 MongoDB 的支持通过提供 org.springframework.dao.support.PersistenceExceptionTranslator 接口的一个实现,将此功能扩展到 MongoDB 数据库。

The Spring framework provides exception translation for a wide variety of database and mapping technologies. T his has traditionally been for JDBC and JPA. The Spring support for MongoDB extends this feature to the MongoDB Database by providing an implementation of the org.springframework.dao.support.PersistenceExceptionTranslator interface.

将它映射到 Spring 的 consistent data access exception hierarchy 背后的动机是你不需要针对 MongoDB 错误代码编写代码即可编写可移植且具有描述性的异常处理代码。所有 Spring 的数据访问异常都继承自根 DataAccessException 类,因此你能够使用一个 try-catch 块来捕获所有数据库相关的异常。请注意,MongoDB 驱动程序抛出的并非所有异常都继承自 MongoException 类。内部异常和消息被保留,因此不会丢失任何信息。

The motivation behind mapping to Spring’s consistent data access exception hierarchy is that you are then able to write portable and descriptive exception handling code without resorting to coding against MongoDB error codes. All of Spring’s data access exceptions are inherited from the root DataAccessException class so that you can be sure to catch all database related exception within a single try-catch block. Note that not all exceptions thrown by the MongoDB driver inherit from the MongoException class. The inner exception and message are preserved so that no information is lost.

MongoExceptionTranslator 执行的一些映射是 com.mongodb.Network到 DataAccessResourceFailureExceptionMongoException 错误代码 1003、12001、12010、12011 和 12012 到 InvalidDataAccessApiUsageException。查阅实现以了解有关映射的更多详细信息。

Some of the mappings performed by the MongoExceptionTranslator are com.mongodb.Network to DataAccessResourceFailureException and MongoException error codes 1003, 12001, 12010, 12011, and 12012 to InvalidDataAccessApiUsageException. Look into the implementation for more details on the mapping.

Domain Type Mapping

MongoDB 文档和域类之间的映射是通过委托给 MongoConverter 接口的实现来完成的。Spring 提供了 MappingMongoConverter,但是你也可以编写自己的转换器。虽然 MappingMongoConverter 可以使用其他元数据来指定对象到文档的映射,但它也可以通过使用一些用来映射 ID 和集合名称的约定来转换不包含其他元数据的对象。这些约定和使用映射注解将在 Mapping 章中进行说明。

The mapping between MongoDB documents and domain classes is done by delegating to an implementation of the MongoConverter interface. Spring provides MappingMongoConverter, but you can also write your own converter. While the MappingMongoConverter can use additional metadata to specify the mapping of objects to documents, it can also convert objects that contain no additional metadata by using some conventions for the mapping of IDs and collection names. These conventions, as well as the use of mapping annotations, are explained in the Mapping chapter.