|
此版本仍在开发中,尚未被视为稳定版。如需最新稳定版本,请使用 Spring Data MongoDB 5.0.4! |
GridFS 支持
MongoDB 支持在其文件系统 GridFS 中存储二进制文件。
Spring Data MongoDB 提供了 GridFsOperations 和 ReactiveGridFsOperations 接口,以及相应的实现类 GridFsTemplate 和 ReactiveGridFsTemplate,以便您与文件系统交互。
您可以通过传入 MongoDatabaseFactory/ReactiveMongoDatabaseFactory 以及 MongoConverter 来设置模板实例,如下示例所示:
-
Imperative
-
Reactive
-
XML
class GridFsConfiguration extends AbstractMongoClientConfiguration {
// … further configuration omitted
@Bean
public GridFsTemplate gridFsTemplate() {
return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
}
}
class ReactiveGridFsConfiguration extends AbstractReactiveMongoConfiguration {
// … further configuration omitted
@Bean
public ReactiveGridFsTemplate reactiveGridFsTemplate() {
return new ReactiveGridFsTemplate(reactiveMongoDbFactory(), mappingMongoConverter());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo
https://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<mongo:db-factory id="mongoDbFactory" dbname="database" />
<mongo:mapping-converter id="converter" />
<bean class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg ref="converter" />
</bean>
</beans>
现在可以注入该模板并用于执行存储和检索操作,如下例所示:
-
Imperative
-
Reactive
class GridFsClient {
@Autowired
GridFsOperations operations;
@Test
public void storeFileToGridFs() {
FileMetadata metadata = new FileMetadata();
// populate metadata
Resource file = … // lookup File or Resource
operations.store(file.getInputStream(), "filename.txt", metadata);
}
}
store(…) 操作接收一个 InputStream、一个文件名,以及(可选的)关于要存储文件的元数据信息。
该元数据可以是任意对象,将由与 MongoConverter 配置在一起的 GridFsTemplate 进行序列化。
或者,您也可以提供一个 Document。
class ReactiveGridFsClient {
@Autowired
ReactiveGridFsTemplate operations;
@Test
public Mono<ObjectId> storeFileToGridFs() {
FileMetadata metadata = new FileMetadata();
// populate metadata
Publisher<DataBuffer> file = … // lookup File or Resource
return operations.store(file, "filename.txt", metadata);
}
}
store(…) 操作接收一个 Publisher<DataBuffer>、一个文件名,以及(可选的)关于要存储文件的元数据信息。
该元数据可以是任意对象,将由与 MongoConverter 配置在一起的 ReactiveGridFsTemplate 进行序列化。
或者,您也可以提供一个 Document。
MongoDB 驱动程序使用 AsyncInputStream 和 AsyncOutputStream 接口来交换二进制流。
Spring Data MongoDB 将这些接口适配为 Publisher<DataBuffer>。
有关 DataBuffer 的更多信息,请参阅 Spring 参考文档。
你可以通过 find(…) 或 getResources(…) 方法从文件系统中读取文件。
让我们先看看 find(…) 方法。
你可以查找单个文件,也可以查找匹配某个 Query 的多个文件。
你可以使用 GridFsCriteria 辅助类来定义查询条件。
它提供了静态工厂方法,用于封装默认的元数据字段(例如 whereFilename() 和 whereContentType()),也可以通过 whereMetaData() 来指定自定义字段。
以下示例展示了如何使用模板查询文件:
-
Imperative
-
Reactive
class GridFsClient {
@Autowired
GridFsOperations operations;
@Test
public void findFilesInGridFs() {
GridFSFindIterable result = operations.find(query(whereFilename().is("filename.txt")));
}
}
class ReactiveGridFsClient {
@Autowired
ReactiveGridFsTemplate operations;
@Test
public Flux<GridFSFile> findFilesInGridFs() {
return operations.find(query(whereFilename().is("filename.txt")))
}
}
目前,MongoDB 在从 GridFS 检索文件时还不支持定义排序条件。因此,传入 Query 方法的 find(…) 实例中所定义的任何排序条件都会被忽略。 |
从 GridFS 读取文件的另一种方式是使用 ResourcePatternResolver 接口所提供的方法。
这些方法允许传入一个 Ant 风格的路径,从而可以检索出匹配给定模式的文件。
以下示例展示了如何使用 GridFsTemplate 来读取文件:
-
Imperative
-
Reactive
class GridFsClient {
@Autowired
GridFsOperations operations;
public GridFsResources[] readFilesFromGridFs() {
return operations.getResources("*.txt");
}
}
class ReactiveGridFsClient {
@Autowired
ReactiveGridFsOperations operations;
public Flux<ReactiveGridFsResource> readFilesFromGridFs() {
return operations.getResources("*.txt");
}
}
GridFsOperations 继承自 ResourcePatternResolver,使得 GridFsTemplate(例如)可以被集成到 ApplicationContext 中,从而从 MongoDB 数据库中读取 Spring 配置文件。
默认情况下,GridFsTemplate 在首次与 GridFS 交互时获取一次 GridFSBucket。
此后,该模板实例会复用缓存的 bucket。
若要使用不同的 bucket,请通过接受 Supplier<GridFSBucket> 参数的构造函数来创建同一个 Template 实例。 |