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 文档之间提供了一个映射。
一旦配置, |
Convenience Methods
MongoTemplate
类实现了 MongoOperations
接口。尽可能让 MongoOperation
上的方法以 MongoDB 驱动器 Collection
对象上可用方法命名,使对习惯使用驱动器 API 的现有的 MongoDB 开发人员而言这个 API 显得较为熟悉。例如,您可以找到诸如 find
、findAndModify
、findAndReplace
、findOne
、insert
、remove
、save
、update
和 updateMulti
等方法。设计目标是尽可能轻松地实现 MongoDB 基本驱动器和 MongoOperations
之间的转换。两个 API 之间的主要区别在于 MongoOperations
可以传递域对象而不是 Document
。此外,MongoOperations
具有用于 Query
、Criteria
和 Update
操作的流畅 API,而不是填充 Document
以指定这些操作的参数。
在 |
Execute Callbacks
MongoTemplate
提供了很多便利方法,可帮助您轻松地执行常见任务。但是,如果您需要直接访问 MongoDB 驱动器的 API,您可以使用几个 Execute
回调方法中的一个。execute
回调为您提供 MongoCollection
或 MongoDatabase
对象的引用。
-
<T> T
execute(Class<?> entityClass, CollectionCallback<T> action)
: 针对指定类实体集合运行给定的CollectionCallback
。 -
<T> T
execute(String collectionName, CollectionCallback<T> action)
: 对给定名称的集合运行给定的CollectionCallback
。 -
<T> T
execute(DbCallback<T> action)
: 运行 DbCallback,按需翻译任何异常。Spring Data MongoDB 为 MongoDB 2.2 版本中引入的聚合框架提供支持。 -
<T> T
execute(String collectionName, DbCallback<T> action)
: 对给定名称的集合运行 DbCallback,按需翻译任何异常。 -
<T> T
executeInSession(DbCallback<T> action)
: 在与数据库的同一次连接中运行给定的DbCallback
,以确保在写入量大的环境中一致性,这样你就可以读取自己写入的数据。
以下示例使用 CollectionCallback
返回有关索引的信息:
-
Imperative
-
Reactive
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();
Fluent API
当涉及到与 MongoDB 的更底层交互时,作为中心组件的 MongoTemplate
提供了各种方法,涵盖了广泛的需求,从集合创建、索引创建和 CRUD 操作到更高级的功能,如 Map-Reduce 和聚合。您可以找到每个方法的多个重载。它们中的大多数涵盖了 API 中可选或可为空的部分。
FluentMongoOperations
为 MongoOperations
的常见方法提供了一个更狭窄的接口,并提供了一个可读性更强、更流畅的 API。入口点(insert(…)
、find(…)
、update(…)
等)遵循一个基于运行操作的自然命名模式。从入口点开始,API 被设计为仅提供导致终止方法(在以下示例中为 all
方法)的上下文相关方法,该终止方法调用实际的 MongoOperations
对应部分:
- 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 | 用于映射在查询中使用的字段的类型。 |
2 | 如果未在域名类型中定义,则使用集合名称。 |
3 | 如果不使用原始域名类型,则使用结果类型。 |
4 | The lookup query.
|
使用投影允许 |
必须不将映射应用于DBRefs。
您可以通过终止方法:first()
、one()
、all()
或 stream()
,在检索一个实体和将多个实体检索为 List
或 Stream
之间进行切换。
使用 near(NearQuery)
编写地理空间查询时,终止方法的数量会发生更改,以仅包括对在 MongoDB 中运行 geoNear
命令有效的方法(在 GeoResults
中将实体获取为 GeoResult
),如下例所示:
-
Imperative
-
Reactive
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();
Exception Translation
Spring 框架为各种各样的数据库和映射技术提供了异常翻译。传统上,这是针对 JDBC 和 JPA 的。Spring 对 MongoDB 的支持通过提供 org.springframework.dao.support.PersistenceExceptionTranslator
接口的一个实现,将此功能扩展到 MongoDB 数据库。
将它映射到 Spring 的 consistent data access exception hierarchy 背后的动机是你不需要针对 MongoDB 错误代码编写代码即可编写可移植且具有描述性的异常处理代码。所有 Spring 的数据访问异常都继承自根 DataAccessException
类,因此你能够使用一个 try-catch 块来捕获所有数据库相关的异常。请注意,MongoDB 驱动程序抛出的并非所有异常都继承自 MongoException
类。内部异常和消息被保留,因此不会丢失任何信息。
MongoExceptionTranslator
执行的一些映射是 com.mongodb.Network到 DataAccessResourceFailureException
和 MongoException
错误代码 1003、12001、12010、12011 和 12012 到 InvalidDataAccessApiUsageException
。查阅实现以了解有关映射的更多详细信息。
Domain Type Mapping
MongoDB 文档和域类之间的映射是通过委托给 MongoConverter
接口的实现来完成的。Spring 提供了 MappingMongoConverter
,但是你也可以编写自己的转换器。虽然 MappingMongoConverter
可以使用其他元数据来指定对象到文档的映射,但它也可以通过使用一些用来映射 ID 和集合名称的约定来转换不包含其他元数据的对象。这些约定和使用映射注解将在 Mapping 章中进行说明。