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();
// 填充元数据
Resource file = … // 查找文件或资源
operations.store(file.getInputStream(), "filename.txt", metadata);
}
}
store(…)
操作接受一个 InputStream
、一个文件名以及(可选的)关于要存储文件的元数据信息。元数据可以是任意对象,它将被配置了 GridFsTemplate
的 MongoConverter
进行序列化。或者,你也可以提供一个 Document
。
class ReactiveGridFsClient {
@Autowired
ReactiveGridFsTemplate operations;
@Test
public Mono<ObjectId> storeFileToGridFs() {
FileMetadata metadata = new FileMetadata();
// 填充元数据
Publisher<DataBuffer> file = … // 查找文件或资源
return operations.store(file, "filename.txt", metadata);
}
}
store(…)
操作接受一个 Publisher<DataBuffer>
、一个文件名以及(可选的)关于要存储文件的元数据信息。元数据可以是任意对象,它将被配置了 ReactiveGridFsTemplate
的 MongoConverter
进行序列化。或者,你也可以提供一个 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 检索文件时定义排序规则。因此,传递给 find(…)
方法的 Query
实例上定义的任何排序规则都将被忽略。
另一种从 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>
的构造函数。