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查看結果
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章