spring-data-mongodb之gridfs

mongodb除了能够存储大量的数据外,还内置了一个非常好用的文件系统。 基于mongodb集群的优势,GridFS当然也是分布式的,而且备份也方便。 当用户把文件上传到GridFS后,文件会被分割成大小为256KB的块,并单独存放。

好处如下:

  1. 可以有Replication;
  2. 可以利用MongoDB的权限访问控制;
  3. 可以利用现成的MongoDB备份方式;

今天主要是学习如何使用data这个框架来操作GridFS,首先配置gridFs的模板类

<!-- Mongodb gridFs的模板 -->
 <bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
     <constructor-arg ref="mongoDbFactory" />
     <constructor-arg ref="mappingConverter" />
 </bean>
/**
  * 上传文件
  * @author yinjihuan
  * @throws Exception
  */
 public static void uploadFile() throws Exception {
     File file = new File("/Users/yinjihuan/Downlaods/logo.png");
     InputStream content = new FileInputStream(file);     //存储文件的额外信息,比如用户ID,后面要查询某个用户的所有文件时就可以直接查询
     DBObject metadata = new BasicDBObject("userId", "1001");
     GridFSFile gridFSFile = gridFsTemplate.store(content, file.getName(), "image/png", metadata);
     String fileId = gridFSFile.getId().toString();
     System.out.println(fileId);
 }

文件默认是上传到数据中的fs.files和fs.chunks中 files是用来存储文件的信息,文件名,md5,文件大小,还有刚刚的metadata,上传时间等等数据,数据格式如下:

{
    "_id": ObjectId("57c17bb0d4c666b6e53ba795"),
    "metadata": {
        "user_id": 1001
    },
    "filename": "file",
    "aliases": null,
    "chunkSize": NumberLong(261120),
    "uploadDate": ISODate("2016-09-08T11:38:24.999Z"),
    "length": NumberLong(165253),
    "contentType": "image/png",
    "md5": "668727a643ddd6df2e98f164d9fc90fd"
}

chunks则是用来存储文件内容的

  1. files_id就是文件的ID,也就是files集合中的_id
  2. n是文件块的索引,通常文件会被分割成256KB的块大小存储
  3. data就是文件的数据了

当需要访问文件的时候通过文件ID可以找到文件被分成了多少块,然后从第一块按顺序开始读取,返回给用户。

{    
    "_id": ObjectId("57c18993d4c6355ffeb6f8ae"),    
    "files_id": ObjectId("57c17bb0d4c666b6e53ba795"),    
    "n": 0,    
    "data": BinData(0,    "iVBORw0KGgDSDDSDDSD5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+Yj5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+YjoA")
}
{   
    "_id": ObjectId("57c18993d4c6355ffeb6f8ae"),    
    "files_id": ObjectId("57c17bb0d4c666b6e53ba795"),    
    "n": 1,    
    "data": BinData(1,    "iVBORw0KGgDSDDSDDSD5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+Yj5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+YjoA")
}
/**
  * 根据文件ID查询文件
  * @author yinjihuan
  * @param fileId
  * @return
  * @throws Exception
  */
 public static GridFSDBFile getFile(String fileId) throws Exception {     
    return gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
 }
/**
  * 根据文件ID删除文件
  * @author yinjihuan
  * @param fileId
  * @throws Exception
  */
 public static void removeFile(String fileId) throws Exception {
     gridFsTemplate.delete(Query.query(Criteria.where("_id").is(fileId)));
 }

如果在Spring mvc中想直接访问存储的文件也很简单,直接通过文件ID查询该文件,然后直接输出到response就是了,记得要设置ContentType,这时就明白为什么存储的时候要把ContentType存起来了。

/**
  * 访问图片
  * @author yinjihuan
  * @param fileId
  * @param request
  * @param response
  */
 @RequestMapping(value = "/image/{fileId}")
 @ResponseBody public void getImage(@PathVariable String fileId, HttpServletResponse response) {     try {
         GridFSDBFile gridfs = filesService.getFile(fileId);
         response.setContentType(gridfs.getContentType());
         OutputStream out = response.getOutputStream();
         gridfs.writeTo(out);         
         out.flush();         
         out.close();
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

原文发布于微信公众号 - 猿天地(cxytiandi)

原文发表时间:2016-09-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏『不羁阁』 | 行走少年郎专栏

iOS多线程:『pthread、NSThread』详尽总结

23050
来自专栏我和PYTHON有个约会

Django来敲门~第一部分【5.1.项目配置settings.py详解】

我们创建好了一个Python项目(mysite/)之后,需要在项目中添加模块应用(polls/),在模块应用中添加处理功能逻辑,如添加模块中的视图处理函数(po...

12230
来自专栏逍遥剑客的游戏开发

C#脚本实践(二): Unity脚本机制分析

24920
来自专栏禹都一只猫博客

Sublime Text 3常用插件

30360
来自专栏木宛城主

ASP.NET MVC 随想录—— 使用ASP.NET Identity实现基于声明的授权,高级篇

在这篇文章中,我将继续ASP.NET Identity 之旅,这也是ASP.NET Identity 三部曲的最后一篇。在本文中,将为大家介绍ASP.NET ...

25780
来自专栏高性能服务器开发

关于windows完成端口(IOCP)的一些理解(一)

系列目录 关于windows完成端口(IOCP)的一些理解(一) 关于windows完成端口(IOCP)的一些理解(二) 关于windows完成端口(IOCP)...

1.2K90
来自专栏张善友的专栏

Contact Manager Web API 示例[3] 分页和查询(Paging and Querying)

联系人管理器web API是一个Asp.net web api示例程序,演示了通过ASP.NET Web API 公开联系信息,并允许您添加和删除联系人,示例地...

23760
来自专栏Java架构沉思录

你真的懂Mybatis缓存机制吗

Mybatis的一级缓存是指Session缓存。一级缓存的作用域默认是一个SqlSession。Mybatis默认开启一级缓存。 也就是在同一个SqlSessi...

1.9K50
来自专栏Java帮帮-微信公众号-技术文章全总结

Hibernate_day01总结

? 第1章 Hibernate_day01总结 今日内容 Hibernate框架的概述 Hibernate的快速入门 Hibernate核心API的介绍 Hi...

35490
来自专栏张善友的专栏

Castle.MVC框架介绍

Castle.MVC目前还在Castle的Sandbox中,只是在源代码管理中有,还没有向外发布版本,这里介绍多时Web的MVC,和Castle的MonoRai...

25780

扫码关注云+社区

领取腾讯云代金券