本文来说下MongoDB中的GridFsTemplate介绍以及基本使用


文章目录

  • GridFsTemplate概述
  • 利用mongodb保存图片/文件/视频两种方式
  • bson二进制简介
  • GridFS简介
  • 程序实例
  • 本文小结



GridFsTemplate概述

GridFsTemplate中封装了一些对GridFs的增删改查操作,本文写几个实例来测试下

mongodb存二进制文件文大小损失 mongodb存储二进制图片_mongodb存二进制文件文大小损失


利用mongodb保存图片/文件/视频两种方式

利用mongodb保存图片/文件/视频 两种方式

  1. 一种是将图片数据转化为bson二进制作为字典的键值对进行保存
  2. 利用mongodb提供的GridFS进行保存

mongodb存二进制文件文大小损失 mongodb存储二进制图片_数据库开发_02


bson二进制简介

BSon是Binary JSON的简称,是一种类Json的一种二进制形式的存储格式 , 主要被MongoDB(目前一个较为流行的非关系数据模型的开源数据库)使用于存储数据和网络数据交换。


GridFS简介

1 GridFS是MongoDB中存储和查询超过BSON文件大小限制(16M)的规范

2 不像BSON文件那样在一个单独的文档中存储文件,GridFS将文件分成多个块,每个块作为一个单独的文档。默认情况下,每个GridFS块是255kB,意味着除了最后一个块之外(根据剩余的文件大小),文档被分成多个255kB大小的块存储。

3 GridFS使用两个集合保存数据,一个集合存储文件块 (fs.files ),另外一个存储文件元数据 ( fs.chunks )

  • fs.files这个集合中存储的是每一个上传到数据库的文档的信息
  • fs.chunks这个集合存储的是上传文件的内容。一个chunk相当于一个文档(大文件被拆分成多个有序的chunk)

4 当从GridFS中获取文件时,MongoDB的驱动程序负责将多个块组装成完整文件 , 以通过GridFS进行范围查询,可以访问文件的任意部分(例如跳到视频文件或者音频文件的任意位置)


程序实例

maven导入

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

yaml文件配置

spring:
  data:
    mongodb:
      host: localhost   #同127.0.0.1
      port: 27017
      database: test    #指定操作的数据库
  servlet:
    multipart:
      max-file-size: 200MB #单个文件上传大小
      max-request-size: 400MB #连续上传文件大小

返回值响应

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author
 * 返回值类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseBean<T> {

    private Integer code;

    private String msg;

    private T data;

}

config配置,文件下载需要使用

@Configuration
public class MongoConfig {


    @Value("${spring.data.mongodb.database}")
    private String db;

    @Bean
    public GridFSBucket getGridFSBucket(MongoClient mongoClient){

        MongoDatabase mongoDatabase = mongoClient.getDatabase(db);
        GridFSBucket bucket = GridFSBuckets.create(mongoDatabase);
        return bucket;
    }
}

使用GridFsTemplate来进行文件的上传,下载,删除,以及基本的信息查询操作

@Slf4j
@RestController
@RequestMapping("/api/file/mongodb")
@Api(tags = "文件上传至mongodb数据库开发测试")
public class FileCommonController {


    @Autowired
    private GridFsTemplate gridFsTemplate;

    @Autowired
    private GridFSBucket gridFSBucket;


    /**
     * 通用上传单个
     * 文件请求
     */
    @SneakyThrows
    @PostMapping("/uploadSingleFile")
    @ApiOperation(value = "上传单个文件")
    public ResponseBean<?> uploadSingleFile(MultipartFile file) {

        // 新文件名
        String originalFilename = file.getOriginalFilename();
        // 获得文件输入流
        InputStream ins = file.getInputStream();
        // 获得文件类型
        String contentType = file.getContentType();

        // 将文件存储到mongodb中,mongodb将会返回这个文件的具体信息
//        ObjectId objectId = gridFsTemplate.store(ins, originalFilename, contentType);

        // 上传文件中我们也可以使用DBObject附加一些属性
        DBObject  metadata = new BasicDBObject();
        metadata.put("hello","word");

        ObjectId objectId = gridFsTemplate.store(ins, originalFilename, contentType, metadata);

        log.info(objectId.toString());
        log.info("接收文件:" + originalFilename);

        //返回信息
        return new ResponseBean<>(200, "上传成功", objectId.toString());
    }



    @ApiOperation(value = "使用MongoDB的ID来获得文件的基本信息")
    @GetMapping(value = "/getFileInfoById")
    public ResponseBean<?> getFileInfoById(@RequestParam(name = "file_id") String fileId) {


        Query query = Query.query(Criteria.where("_id").is(fileId));
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);

        String value = (String)gridFSFile.getMetadata().get("hello");
        log.info("==============================>" + value);

        if(gridFSFile == null){

            log.info("文件不存在");
            return new ResponseBean<>(400, "fail", "文件不存在");
        }
        //返回信息
        return new ResponseBean<>(200, "success", gridFSFile.toString());
    }



    @ApiOperation(value = "使用MongoDB的ID来删除文件")
    @GetMapping(value = "/deleteFileById")
    public ResponseBean<?> deleteFileById(@RequestParam(name = "file_id") String fileId) {

        Query query = Query.query(Criteria.where("_id").is(fileId));

        // 删除之前先看文件是否存在
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);
        if(gridFSFile == null){

            log.info("文件删除失败,文件不存在");
            return new ResponseBean<>(400, "删除失败", "文件不存在");
        }

        gridFsTemplate.delete(query);
        log.info("文件删除成功");
        //返回信息
        return new ResponseBean<>(200, "删除成功", gridFSFile.toString());
    }

    @ApiOperation(value = "使用MongoDB的ID来下载文件")
    @GetMapping(value = "/downloadFileById")
    @SneakyThrows
    public byte[] downloadFileById(@RequestParam(name = "file_id") String fileId, HttpServletResponse response)  {


        Query query = Query.query(Criteria.where("_id").is(fileId));
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);

        // 解决文件下载的时候,中文乱码的问题
        String name = new String(gridFSFile.getFilename().getBytes("GBK"), "ISO-8859-1");

        response.setHeader("Content-Disposition", "attachment;fileName=" + name);

        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());

        //创建gridFsResource,用于获取流对象
        GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);

        log.info(gridFSFile.getFilename() + "=======>下载成功!!");

        return IOUtils.toByteArray(gridFsResource.getInputStream());
    }


}

文件测试,程序中的这几个接口都是测试过的

mongodb存二进制文件文大小损失 mongodb存储二进制图片_数据库_03

navicat查看文件

mongodb存二进制文件文大小损失 mongodb存储二进制图片_上传_04


本文小结

本文介绍了使用GridFsTemplate来进行简单的文本操作,文件上传,文件下载等。