首頁>技術>

時隔倆月再次前來更新,太忙了。這次把從年前持續到現在的一個專案用到的mongodb技術總結一下。陸陸續續遇到的坑和經驗也放進來。

首先是技術選型上,我為啥選擇使用mongodb,而不是mysql?

這個完全是看業務場景,業務場景會導致資料的特殊性。我負責的內容管理部分。主要是儲存使用者和內容的互動資料。資料量比較大,而且都是新增動作,沒有修改。且每條資料的欄位如果是mysql,會存在很多varchar長度超過200,text的欄位。所以選擇使用mongodb.

1.首先專案引入依賴

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);

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

原文連結:https://blog.csdn.net/zhanglf02/article/details/114032214

9
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 常規和遞迴實現單鏈表的刪除操作