springboot MongoTemplate实现常见操作

共 12663字,需浏览 26分钟

 ·

2021-03-03 11:00

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

76套java从入门到精通实战课程分享

时隔俩月再次前来更新,太忙了。这次把从年前持续到现在的一个项目用到的mongodb技术总结一下。陆陆续续遇到的坑和经验也放进来。


首先是技术选型上,我为啥选择使用mongodb,而不是mysql?


这个完全是看业务场景,业务场景会导致数据的特殊性。我负责的内容管理部分。主要是存储用户和内容的交互数据。数据量比较大,而且都是新增动作,没有修改。且每条数据的字段如果是mysql,会存在很多varchar长度超过200,text的字段。所以选择使用mongodb.


1.首先项目引入依赖

        <!--集成mongodb-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

2.然后配置文件加上连接mongodb的配置

spring: 
  data:
    mongodb:
      host: mongodb-server
      port: 27017
      database: content


3.在具体项目的类中注入MongoTemplate 

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
 
 
    @Autowired
    private MongoTemplate mongoTemplate;
 


4.封装实体类,其中Document的注解至关重要。这个影响查询时能不能查询到数据

import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.mongodb.core.mapping.Document;
 
import java.io.Serializable;
import java.util.Date;
@Document(collection="homework_multimedia_detail")
public class HomeworkMultimediaDetailDocument implements Serializable {
    private static final long serialVersionUID = 8653911691313041614L;
    @ApiModelProperty(value = "课堂标识", required = true)
    private Long virtualClassId;
    ......
}


5.具体的service操作mongodb库


5.1 保存数据到mongodb

        int num = Math.abs(studentUserId.intValue()) % 10;
        String tableName = String.format("%s_%d""homework_multimedia_detail", num);
        LOGGER.info("tableName:{}",tableName);
        
        HomeworkMultimediaDetailDocument homeworkMultimediaDetailDocument = new HomeworkMultimediaDetailDocument();
        BeanUtils.copyProperties(multimediaHomeworkParam,homeworkMultimediaDetailDocument);
        homeworkMultimediaDetailDocument.setVirtualClassId(virtualClassId);
        homeworkMultimediaDetailDocument.setClassTypeId(classTypeId);
        homeworkMultimediaDetailDocument.setStudentUserId(studentUserId);
        homeworkMultimediaDetailDocument.setVoiceUrl(voiceS3Url);
        homeworkMultimediaDetailDocument.setCreateTime(DateUtil.localTime());
        //分库保存基础数据到mongodb,确保在用户状态先入库在入库mongodb!
        mongoTemplate.insert(homeworkMultimediaDetailDocument, TABLE_NAME);


5.2 mongodb的简单查询

Query query = new Query();
            query.addCriteria(Criteria.where("virtualClassId").is(homeworkMultimedia.getVirtualClassId())
                    .and("studentUserId").is(homeworkMultimedia.getStudentUserId())
                    .and("classTypeId").is(homeworkMultimedia.getClassTypeId())
                    .and("lessonId").is(homeworkMultimedia.getLessonId())
                    .and("createTime").gte(homeworkMultimedia.getCreateTime()).lte(nowAfterSeconds)
            );
            List<HomeworkMultimediaDetailDocument> homeworkMultimediaDetailDocumentList = mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class);


5.3 复杂的查询 多条件,分页,排序查询

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
 
 
 
public Map getStudentMultimediaHomeworkByConditions(List<Long> studentUserIdList, Integer lessonNo, Date startTime, Date endTime,
                                                        Integer pageNum, Integer pageSize, String sortField, String sortValue) {
        Map map = new HashMap<>();
        List<MultimediaResources> multimediaResourcesList = new ArrayList<>();
        Sort sort = null;
        if (StringUtils.isEmpty(sortField)) {
            sortField = "createTime";
        }
        if (StringUtils.isEmpty(sortValue)) {
            sortValue = Constants.SORT_DESC;
        }
        if (sortValue.toLowerCase().equals(Constants.SORT_DESC)) {
            sort = Sort.by(Sort.Direction.DESC, sortField);
        } else {
            sort = Sort.by(Sort.Direction.ASC, sortField);
        }
        Criteria criteria = Criteria.where("version").gte(1);
        if (lessonNo != null && lessonNo > 0) {
            criteria.and("lessonNo").is(lessonNo);
        }
        if (studentUserIdList != null && studentUserIdList.size() > 0) {
            criteria.and("studentUserId").in(studentUserIdList);
        }
        if (startTime != null) {
            if (endTime != null) {
                criteria.and("createTime").gte(startTime).lte(endTime);
            } else {
                criteria.and("createTime").gte(startTime);
            }
        } else {
            if (endTime != null) {
                criteria.and("createTime").lte(endTime);
            }
        }
        Query query = Query.query(criteria);
        //首先查询部分也的总条数
        Long count = mongoTemplate.count(query, HomeworkMultimediaDetailDocument.class);
        //导出功能没有分页
        if (pageNum != null && pageSize != null) {
            PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
            query.with(pageRequest);
        }
        query.with(sort);
        //然后分页,排序查询具体的list,获取到本节的作业内容具体数据。
        List<HomeworkMultimediaDetailDocument> homeworkMultimediaDetailDocumentList = mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class);
        if (homeworkMultimediaDetailDocumentList != null && homeworkMultimediaDetailDocumentList.size() > 0) {
            homeworkMultimediaDetailDocumentList.forEach(homeworkMultimediaDetailDocument -> {
                MultimediaResources multimediaResources = new MultimediaResources();
                BeanUtils.copyProperties(homeworkMultimediaDetailDocument, multimediaResources);
                multimediaResourcesList.add(multimediaResources);
            });
        }
        map.put("total", count);
        map.put("list", multimediaResourcesList);
        return map;
    }


以上是具体的生产demo


坑:mongodbTemplate的分页第一页不是从1开始,而是从0开始。并且新的方法已经不是通过new创建对象。而是这样:PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);Sort sort = Sort.by(Sort.Direction.DESC, sortField);


经验1:Query query = Query.query(criteria); 与 Query query = new Query();query.addCriteria(criteria)效果一样。mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class,collectionName)与mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class)+HomeworkMultimediaDetailDocument注解上映射关系效果一样。


经验2:聚合操作Aggregation完全可以使用Criteria+Query来代替。最多通过java代码做些处理。当然,如果Aggregation你能正确查询也很厉害。Query支持单个字段多种条件,多个字段排序,分页功能。


经验3:Query支持的条件查询一个字段只能出现一次。像这样:criteria.and("createTime").gte(startTime).lte(endTime);如果你这样写就会运行报错:criteria.and("createTime").gte(startTime); criteria.and("createTime").lte(endTime);


以上便是使用的一些经验总结。希望对你有所帮助。

————————————————

版权声明:本文为CSDN博主「万米高空」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/zhanglf02/article/details/114032214




锋哥最新SpringCloud分布式电商秒杀课程发布

👇👇👇

👆长按上方微信二维码 2 秒





感谢点赞支持下哈 

浏览 103
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报