当前位置: 首页 > 工具软件 > GridFS > 使用案例 >

学习mongoDB:基本CRUD & GridFS存储各种文件 & 动态查询

岳亮
2023-12-01

写在最前面:

推荐个大神写的 mongo实现动态查询

https://www.cnblogs.com/wslook/p/9275861.html

下面试学习mongoDB的基本使用,这里使用的是spring boot 集成 mongodb

一、pom依赖

安装好mongoDB之后,需要在项目pom中导入依赖

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

配置参数

spring:
  data:
    mongodb:
      host: xx.xx.xx.xx
      port: xxxx
      username: xxxx
      password: xxxx
      database: xxxx
  #设置允许文件大小
  servlet:
       multipart:
         max-file-size:  200MB
         max-request-size:  200MB

二、 集合curd

Q1:集合是什么?
答:等同于 mysql 中的 table

Q2:spring boot怎么操作 mongo?
答:可以直接使用mongoTemplate的API,也可以使用MongoRepository的API。
mongoTemplate类似于JDBCTemplate,MongoRepository类似于mybatis

1:创建对象

主键使用Long型,mongo默认使用 _id作为主键


import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class DemoEasy {
    /**
     * 主键id
     * @Id 注解会将对象里的id字段,转化为mongodb中的 _id
     * _id默认是ObjectId类型(有4个字段),但是ObjectId.toString() 会得到一个字符串,后续查询使用要使用这个字符串
     **/
    @Id
    private Long id;
    /**
     * 姓名
     **/
    private String name;
    /**
     * 年龄
     **/
    private Integer age;
    /**
     * 工作
     **/
    private String job;
    /**
     * 兴趣爱好
     **/
    private String like;
    /**
     * 备注
     **/
    private String remark;
    /**
     * 备注
     **/
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime = new Date();
}

2:写个接口和实现类,实现MongoRepository

说明:

1:如果不使用MongoRepository,那么可以不用写这个接口和实现类。
只需要在controller类里面直接用mongoTemplate。

2:如果仅用MongoRepository自带的API,可以不写实现类。

import com.tao.demoEasy.model.DemoEasy;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface IDemoEasyService extends MongoRepository<DemoEasy, Long> {

    List<DemoEasy> findByName(String name);

}

import com.tao.demoEasy.model.DemoEasy;
import com.tao.demoEasy.service.IDemoEasyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;

import java.util.List;

public class DemoEasyServiceImpl extends SimpleMongoRepository<DemoEasy, Long> implements IDemoEasyService {

    @Autowired
    private MongoTemplate mongoTemplate;
    public DemoEasyServiceImpl(MongoEntityInformation<DemoEasy, Long> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
    }

    @Override
    public List<DemoEasy> findByName(String name) {
        List<DemoEasy> retult = mongoTemplate.find(Query.query(Criteria.where("name").regex(name)), DemoEasy.class);
        return retult;
    }
}

3:controller开始调用api

1:使用mongoTemplate
mongoTemplate可以结合Criteria、Aggregation、Query等实现动态查询,当然实现代码要稍微复杂些


    @Autowired
    private MongoTemplate mongoTemplate;
    //---------------------------使用 mongoTemplate 进行查询 ---------------------------------
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public String save(@RequestBody JSONObject jsonObject) {
        JSONObject demoEasy = mongoTemplate.save(jsonObject, "demoEasy");
        return demoEasy.getString("_id");
    }

    @RequestMapping(value = "find", method = RequestMethod.POST)
    public JSONObject find(@RequestBody JSONObject jsonObject) {
        Query query = new Query(Criteria.where("_id").is(jsonObject.getString("id")));
        JSONObject one = mongoTemplate.findOne(query, JSONObject.class);
        return one;
    }

    @RequestMapping(value = "update", method = RequestMethod.POST)
    public Object update(@RequestBody DemoEasy model) {
        //查询条件
        Query query = new Query(Criteria.where("id").is(model.getId()));
        //按需更新字段
        Update update = new Update();
        if (StringUtils.isNotBlank(model.getName())) {
            update.set("name", model.getName());
        }
        if (StringUtils.isNotBlank(model.getJob())) {
            update.set("job", model.getJob());
        }
        if (null != model.getAge()) {
            update.set("age", model.getAge());
        }
        if (StringUtils.isNotBlank(model.getRemark())) {
            update.set("remark", model.getRemark());
        }
        //执行更新语句
        return mongoTemplate.updateFirst(query, update, DemoEasy.class);
    }

2:使用MongoRepository
MongoRepository自带的API用起来要简单些…要先熟悉下ExampleMatcher 的用发

    
    @Autowired
    private IDemoEasyService iDemoEasyService;
//---------------------------使用 demoEasyService MongoRepository 进行查询 ---------------------------------

    /**
     * 增加单个对象
     **/
    @RequestMapping(value = "insert", method = RequestMethod.POST)
    public DemoEasy insert(@RequestBody DemoEasy model) {
        model.setCreateTime(new Date());
        DemoEasy save = iDemoEasyService.save(model);
        return save;
    }

    /**
     * 增加多个对象
     **/
    @RequestMapping(value = "insertBatch", method = RequestMethod.POST)
    public List<DemoEasy> insertBatch(@RequestBody List<DemoEasy> model) {
        List<DemoEasy> save = iDemoEasyService.saveAll(model);
        return save;
    }

    /**
     * 根据id删除一个数据
     **/
    @RequestMapping(value = "remove", method = RequestMethod.POST)
    public void remove(@RequestBody DemoEasy model) {
        iDemoEasyService.deleteById(model.getId());
    }


    @RequestMapping(value = "findById", method = RequestMethod.POST)
    public Object findById(@RequestBody DemoEasy model) {
        log.debug("--mongodb_tao开始查询 jSONObject集合");
        return iDemoEasyService.findById(model.getId());
    }


    /**
     * 分页查询
     **/
    @RequestMapping(value = "listPage", method = RequestMethod.POST)
    public Page<DemoEasy> listPage(@RequestBody DemoEasy model) {
        //排序
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        //设置分页参数 -- 默认分页参数
        PageRequest pageRequest = PageRequest.of(0, 5, sort);
        if (model.getPageNum() != null && model.getPageSize() != null) {
            pageRequest = PageRequest.of((model.getPageNum()-1), model.getPageSize(), sort);
        }
        //查询条件:模糊匹配name字段
        ExampleMatcher matcher = ExampleMatcher.matching().
                //改变默认字符串匹配为:模糊查询
                        withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING).
                //name字段模糊匹配
                        withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());

        DemoEasy query = new DemoEasy();
        query.setName(model.getName());
        Example<DemoEasy> example = Example.of(query, matcher); //动态查询
        Page<DemoEasy> result = iDemoEasyService.findAll(example, pageRequest);
        return result;
    }

    /**
     * todo 列表查询全量数据
     * 条件:name字段模糊匹配 根据id进行排序
     **/
    @RequestMapping(value = "list", method = RequestMethod.POST)
    public List<DemoEasy> list(@RequestBody DemoEasy model) {
        //排序
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        //模糊匹配
        ExampleMatcher matcher = ExampleMatcher.matching().
                withMatcher("name", ExampleMatcher.GenericPropertyMatcher::contains);
        //查询
        Example<DemoEasy> example = Example.of(model, matcher);
        List<DemoEasy> result = iDemoEasyService.findAll(example, sort);
        return result;
    }

三、GrigFS

Q1:都说mongo可以直接存储各种文档的。那么到底要怎么实现(通过API直接把各种文件直接存到mongo中)?
答: 使用GridFsTemplate的API,可以直接把文件写入mongo。

1:创建一个非必须的对象

主要是用在GridFS的数据源(类似于备注),所有没有这个对象也可以。

@Data
public class BaseFileModel {
    @Id
    private Long id;
    private Long fileSize;
    private String fileBeLong;
    private String remark;
}

2:给GridFS指定桶

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;

@Configuration
public class MongoConfig { 

    @Bean
    public GridFsTemplate gridFsTemplate(MongoDbFactory dbFactory, MongoConverter converter) {
        return new GridFsTemplate(dbFactory, converter, "gridFS_tao");
    }

}

3:controller调用API

@RestController
@RequestMapping(value = "fileMongo")
public class FileMongoController {

    @Autowired
    private GridFsTemplate gridFsTemplate;

    /**
     * 文件的存储
     **/
    @RequestMapping(value = "saveFile", method = RequestMethod.POST)
    public String saveFile(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "fileName") String fileName) throws IOException {
        InputStream inputStream = file.getInputStream();
        //BaseFileModel baseFileModel = new BaseFileModel();
        //baseFileModel.setFileSize(file.getSize());
        //baseFileModel.setRemark("test file save");
        //baseFileModel.setFileBeLong("zhang_san");
        //ObjectId store = gridFsTemplate.store(inputStream, fileName, file.getContentType(), baseFileModel);
        ObjectId store = gridFsTemplate.store(inputStream, fileName, file.getContentType());
        return store.toString();
    }

    /**
     *  获取文件
     **/

    @RequestMapping(value = "getFile/{id}", method = RequestMethod.GET)
    public void getFile(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
        GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id)));
        //设置contentType,  这个比较重要,没有的话,会默认返回页面.zip文件,且里面奇奇怪怪的
        response.setContentType(gridFSFile.getMetadata().getString("_contentType"));
        //获取流对象
        GridFsResource resource = gridFsTemplate.getResource(gridFSFile);
        //获取流中的数据
        byte[] bytes = IOUtils.toByteArray(resource.getInputStream());
        OutputStream out = response.getOutputStream();
        //byte数组用于存放字节数据
        out.write(bytes);
       //关闭响应输出流
        out.close();
    }
    
    /**
     * 文件的删除
     **/
    @RequestMapping(value = "deleteFile/{id}", method = RequestMethod.DELETE)
    public void deleteFile(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
        gridFsTemplate.delete(new Query(Criteria.where("_id").is(id)));
    }
}

总结

以上就是mongo的简单使用。
ps:
1: 搭建mongoDB时,自定义数据库有点坑。
2: ExampleMatcher matcher = ExampleMatcher.matching() 后面跟的条件,只能用’.'连接,不能像mybatis-plus的QueryWrapper一样。不知道有没有更加简介的书写方式

 类似资料: