springboot MongoTemplate实现常见操作
点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
时隔俩月再次前来更新,太忙了。这次把从年前持续到现在的一个项目用到的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 秒
感谢点赞支持下哈