我最近发现了 GridFS,我想用它来存储带有元数据的文件。我只是想知道是否可以使用 MongoRepository
来查询 GridFS?如果是,有人可以举个例子吗?
如果有的话,我也会采用 Hibernate 的解决方案。
原因是:我的元数据包含许多不同的字段,查询存储库要比为每个字段编写一些 new Query(Criteria.where(...))
容易得多设想。我希望也可以简单地获取一个 Java 对象并通过 REST API 提供它,而不需要文件本身。
编辑:我正在使用
- Spring 4 测试版
- Spring Data Mongo 1.3.1
- 休眠 4.3 测试版
最佳答案
有办法解决这个问题:
@Document(collection="fs.files")
public class MyGridFsFile {
@Id
private ObjectId id;
public ObjectId getId() { return id; }
private String filename;
public String getFilename() { return filename; }
private long length;
public long getLength() { return length; }
...
}
您可以为此编写一个普通的 Spring Mongo Repo。现在您至少可以使用 Spring Data Repo 查询 fs.files
集合。 但是:您无法通过这种方式访问文件内容。
要获取文件内容本身,您有(至少)2 个选项:
使用
file = gridOperations.findOne(Query.query(Criteria.where("_id").is(id)));
InputStream is = file.getInputStream( );
看看
GridFSDBFile
的源码。在那里你可以看到,它如何在内部查询fs.chunks
集合并填充 InputStream。
(选项 2 非常低级,选项 1 更容易,并且此代码由 MongoDB-Java-Driver 开发人员维护,尽管选项 1 是我的选择)。
更新 GridFS 条目:
- GridFS并非旨在更新文件内容!
- 虽然只更新
metadata
字段会很有用。其余字段有点静态。
您应该能够简单地使用您的自定义 MyGridFsFileRepo
的 update
方法。我建议仅为 metadata
字段创建一个 setter 。
不同文件的不同元数据:
我使用具有通用元数据的 abstract MyGridFsFile
类解决了这个问题,即:
@Document(collection="fs.files")
public abstract class AbstractMyGridFsFile<M extends AbstractMetadata> {
...
private M metadata;
public M getMetadata() { return metadata; }
void setMetadata(M metadata) { this.metadata = metadata; }
}
当然,每个 impl 都有自己的 AbstractMetadata
impl 关联。我做了什么? AbstractMetadata
总是有一个名为 type
的字段。这样我就可以找到正确的 AbstractMyGridFsFile
impl。虽然我也有一个通用的抽象存储库。
顺便说一句:与此同时,我从使用 Spring Repo 切换到通过 MongoTemplate
使用普通访问,例如:
protected List<A> findAll(Collection<ObjectId> ids) {
List<A> files = mongoTemplate.find(Query.query(Criteria
.where("_id").in(ids)
.and("metadata.type").is(type) // this is hardcoded for each repo impl
), typeClass); // this is the corresponding impl of AbstractMyGridFsFile
return files;
}
希望这会有所帮助。如果您需要有关此的更多信息,我可以写更多。告诉我吧。
关于Spring Data + MongoDB GridFS 可以通过 Repository 访问吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19043654/