Java SpringBoot MongoTemplate

1、项目引入依赖操作MongoDB的依赖

  1. <!--集成mongodb-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-mongodb</artifactId>
  5. <version>2.2.6.RELEASE</version>
  6. </dependency>

2、然后配置文件加上连接MongoDB的配置

  1. spring:
  2. data:
  3. mongodb:
  4. host: mongodb-server
  5. port: 27017
  6. database: content

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

  1. import org.springframework.data.mongodb.core.MongoTemplate;
  2. import org.springframework.data.mongodb.core.query.Criteria;
  3. import org.springframework.data.mongodb.core.query.Query;
  4. @Autowired
  5. private MongoTemplate mongoTemplate;

4、封装实体类

其中Document的注解至关重要。这个影响查询时能不能查询到数据

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

5、具体的service操作mongodb库

5.1 保存数据到mongodb

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

5.2 mongodb的简单查询

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

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

  1. import org.springframework.data.domain.PageRequest;
  2. import org.springframework.data.domain.Sort;
  3. import org.springframework.data.mongodb.core.MongoTemplate;
  4. import org.springframework.data.mongodb.core.query.Criteria;
  5. import org.springframework.data.mongodb.core.query.Query;
  6. public Map getStudentMultimediaHomeworkByConditions(List<Long> studentUserIdList, Integer lessonNo, Date startTime, Date endTime,
  7. Integer pageNum, Integer pageSize, String sortField, String sortValue) {
  8. Map map = new HashMap<>();
  9. List<MultimediaResources> multimediaResourcesList = new ArrayList<>();
  10. Sort sort = null;
  11. if (StringUtils.isEmpty(sortField)) {
  12. sortField = "createTime";
  13. }
  14. if (StringUtils.isEmpty(sortValue)) {
  15. sortValue = Constants.SORT_DESC;
  16. }
  17. if (sortValue.toLowerCase().equals(Constants.SORT_DESC)) {
  18. sort = Sort.by(Sort.Direction.DESC, sortField);
  19. } else {
  20. sort = Sort.by(Sort.Direction.ASC, sortField);
  21. }
  22. Criteria criteria = Criteria.where("version").gte(1);
  23. if (lessonNo != null && lessonNo > 0) {
  24. criteria.and("lessonNo").is(lessonNo);
  25. }
  26. if (studentUserIdList != null && studentUserIdList.size() > 0) {
  27. criteria.and("studentUserId").in(studentUserIdList);
  28. }
  29. if (startTime != null) {
  30. if (endTime != null) {
  31. criteria.and("createTime").gte(startTime).lte(endTime);
  32. } else {
  33. criteria.and("createTime").gte(startTime);
  34. }
  35. } else {
  36. if (endTime != null) {
  37. criteria.and("createTime").lte(endTime);
  38. }
  39. }
  40. Query query = Query.query(criteria);
  41. //首先查询部分也的总条数
  42. Long count = mongoTemplate.count(query, HomeworkMultimediaDetailDocument.class);
  43. //导出功能没有分页
  44. if (pageNum != null && pageSize != null) {
  45. PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
  46. query.with(pageRequest);
  47. }
  48. query.with(sort);
  49. //然后分页,排序查询具体的list,获取到本节的作业内容具体数据。
  50. List<HomeworkMultimediaDetailDocument> homeworkMultimediaDetailDocumentList = mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class);
  51. if (homeworkMultimediaDetailDocumentList != null && homeworkMultimediaDetailDocumentList.size() > 0) {
  52. homeworkMultimediaDetailDocumentList.forEach(homeworkMultimediaDetailDocument -> {
  53. MultimediaResources multimediaResources = new MultimediaResources();
  54. BeanUtils.copyProperties(homeworkMultimediaDetailDocument, multimediaResources);
  55. multimediaResourcesList.add(multimediaResources);
  56. });
  57. }
  58. map.put("total", count);
  59. map.put("list", multimediaResourcesList);
  60. return map;
  61. }

6、使用过程中需要注意的问题

6.1 mongodbTemplate分页

mongodbTemplate的分页第一页不是从1开始,而是从0开始。并且新的方法已经不是通过new创建对象。而是这样:

  1. PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
  2. Sort sort = Sort.by(Sort.Direction.DESC, sortField);

6.2 经验1

  1. Query query = Query.query(criteria);

  1. Query query = new Query();query.addCriteria(criteria);

效果一样。

  1. mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class,collectionName)

  1. mongoTemplate.find(query, HomeworkMultimediaDetailDocument.class)+HomeworkMultimediaDetailDocument

注解上映射关系效果一样。

6.3 经验2

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

6.4 经验3

Query支持的条件查询一个字段只能出现一次。像这样:

  1. criteria.and("createTime").gte(startTime).lte(endTime);

如果这样写就会运行报错,正确的写法如下:

  1. criteria.and("createTime").gte(startTime);
  2. criteria.and("createTime").lte(endTime);