Template API
位于 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> Texecute(Class<?> entityClass, CollectionCallback<T> action): 针对指定类实体集合运行给定的CollectionCallback。 -
<T> Texecute(String collectionName, CollectionCallback<T> action): 对给定名称的集合运行给定的CollectionCallback。 -
<T> Texecute(DbCallback<T> action): 运行 DbCallback,按需翻译任何异常。Spring Data MongoDB 为 MongoDB 2.2 版本中引入的聚合框架提供支持。 -
<T> Texecute(String collectionName, DbCallback<T> action): 对给定名称的集合运行 DbCallback,按需翻译任何异常。 -
<T> TexecuteInSession(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> 用于映射在查询中使用的字段的类型。 <1> 如果未在域名类型中定义,则使用集合名称。 <1> 如果不使用原始域名类型,则使用结果类型。 <1> The lookup query.
- Reactive
-
Flux<Jedi> all = template.query(SWCharacter.class) .inCollection("star-wars") .as(Jedi.class) .matching(query(where("jedi").is(true))) .all();
|
使用投影允许 |
必须不将映射应用于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 章中进行说明。