GridFS Support

MongoDB 支持在其文件系统 GridFS 中存储二进制文件。Spring Data MongoDB 提供 GridFsOperationsReactiveGridFsOperations 接口以及相应的实现 GridFsTemplateReactiveGridFsTemplate,让你可以与文件系统进行交互。你可以通过将 MongoDatabaseFactory/ReactiveMongoDatabaseFactoryMongoConverter 交付给模板实例来设置模板实例,如下例所示:

  • 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>

现在可以注入并使用该模板来执行存储和检索操作,如下例所示:

Using GridFS to store files
  • Imperative

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

Reactive
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 的驱动程序使用 AsyncInputStreamAsyncOutputStream 接口交换二进制流。Spring Data MongoDB 将这些接口调整为 Publisher<DataBuffer>。在 Spring’s reference documentation 中阅读有关 DataBuffer 的更多信息。

你可以通过 find(…)getResources(…) 方法从文件系统读取文件。让我们先看一下 find(…) 方法。你可以找到单个文件或匹配 Query 的多个文件。你可以使用 GridFsCriteria 帮助程序类来定义查询。它提供静态工厂方法来封装默认元数据字段(如 whereFilename()whereContentType())或通过 whereMetaData() 自定义字段。以下示例展示如何使用模板查询文件:

Using GridFsTemplate to query for files
  • 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 读取文件:

Using GridFsTemplate to read files
  • 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> 的构造函数。