GridFS实现mongodb文件存储

一. GridFS介绍:
mongodb数据库支持文件存储,GridFS是MongoDB提供的用于持久化存储文件的模块.

GridFS工作原理是:
在GridFS存储文件是将文件分块存储,文件会按照256KB的大小分割成多个块进行存储,GridFS使用两个集合(collection)存储文件,一个集合是chunks, 用于存储文件的二进制数据;一个集合files,用于存储文件的元数据信息(文件名称、块大小、上传时间等信息)。
从GridFS中读取文件要对文件的各各块进行组装、合并。
在这里插入图片描述

二. 需求说明
使用GridFS实现mongodb文件存储

三. 实现方案
spring data mongodb提供了操作gridFS的方法,通过@Autowired注入GridFsTemplate和GridFsBucket并调用其方法可以实现mongodb文件存储,将文件实际数据保存到fs.chunks集合并将文件信息保存到fs.files集合中.

四. 实现步骤
1.cms项目在此之前已集合spring data mongodb

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

配置文件

spring:
  application:
    name: sc-multipl-manage-cms # 服务名称
  ## 配置数据库连接
  data:
    ## mongoDB
    mongodb:
      uri:  mongodb://localhost:27017
      database: xc_cms
  1. 文件操作实体类
public class CmsFile {

    private String fileId;
    private String fileName;
    private String md5;

}
  1. 编写Service,实现文件上传下载和删除功能
@Service
public class CmsFileServiceImpl implements CmsFileService {


    @Autowired
    GridFsTemplate gridFsTemplate;

    @Autowired
    GridFSBucket gridFSBucket;

    @Override
    public CmsFile uploadFileToMongo(MultipartFile file) {
        //获取上传文件名,包含后缀
        String originalFilename = file.getOriginalFilename();
        //获取后缀
        String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
        //使用uuid加.后缀的方式生成文件名
        String dFileName = UUID.randomUUID() + substring;
        //获取出入流
        InputStream inputStream = null;
        ObjectId objectId = null;
        try {
            inputStream = file.getInputStream();
            objectId = gridFsTemplate.store(inputStream, dFileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (objectId == null) {
            ExceptionCast.cast(CmsCode.CMS_UPLOADFILE_FAIL);
        }
        CmsFile cmsFile = new CmsFile();
        cmsFile.setFileId(objectId.toString());
        cmsFile.setFileName(dFileName);
        return cmsFile;
    }

    @Override
    public String getFileStringByFileId(String fileId) {

        //根据id查询文件
        GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
        if (gridFSFile == null){
            ExceptionCast.cast(CmsCode.CMS_FILE_NOTEXISTS);
        }
        //打开下载流对象
        GridFSDownloadStream downloadStream =
                gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
        //创建gridFsResource,用于获取流对象
        GridFsResource gridFsResource = new GridFsResource(gridFSFile, downloadStream);
        String fileString = null;
        try {
            //获取流中的数据
            fileString = IOUtils.toString(gridFsResource.getInputStream(), "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileString;
    }

    @Override
    public boolean deleteFileByFileId(String fileId) {
        if (StringUtils.isNotBlank(fileId)){
            //根据文件id删除fs.files和fs.chunks中的记录
            gridFsTemplate.delete(Query.query(Criteria.where("_id").is(fileId)));
        }
        return true;
    }
}

4.编写controller类

@RestController
@RequestMapping("/cms/file")
public class CmsFileController implements CmsFileControllerApi {

    @Autowired
    CmsFileService cmsFileService;

    @Override
    @RequestMapping("uploadFileToMongo")
    public QueryListResult<CmsFile> uploadFileToMongo(@RequestParam("file") MultipartFile file) {

        CmsFile cmsFile = cmsFileService.uploadFileToMongo(file);
        ListResult<CmsFile> listResult = new ListResult<>();
        listResult.setTotal(1);
        List<CmsFile> list = new ArrayList<>();
        list.add(cmsFile);
        listResult.setList(list);
        return QueryListResult.returnSuccess(listResult);
    }

    @Override
    @GetMapping("getFileStringByFileId/{fileId}")
    public QueryOneResult<String> getFileStringByFileId(@PathVariable("fileId") String fileId) {
        String fileString = cmsFileService.getFileStringByFileId(fileId);
        OneResult<String> oneResult = new OneResult<>();
        oneResult.setResult(fileString);
        return QueryOneResult.returnSuccess(oneResult);
    }

    @Override
    @GetMapping("deleteFileByFileId/{fileId}")
    public ResponseResult deleteFileByFileId(@PathVariable("fileId") String fileId) {
        boolean result = cmsFileService.deleteFileByFileId(fileId);
        return result?ResponseResult.returnSuccess():ResponseResult.returnFail();
    }
}

最后,测试,我用的是postman,并在fschunks和fs.files查看结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/chenhaotao/article/details/86634946