springboot MongoTemplate實(shí)現(xiàn)常見操作
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
76套java從入門到精通實(shí)戰(zhàn)課程分享
時(shí)隔倆月再次前來(lái)更新,太忙了。這次把從年前持續(xù)到現(xiàn)在的一個(gè)項(xiàng)目用到的mongodb技術(shù)總結(jié)一下。陸陸續(xù)續(xù)遇到的坑和經(jīng)驗(yàn)也放進(jìn)來(lái)。
首先是技術(shù)選型上,我為啥選擇使用mongodb,而不是mysql?
這個(gè)完全是看業(yè)務(wù)場(chǎng)景,業(yè)務(wù)場(chǎng)景會(huì)導(dǎo)致數(shù)據(jù)的特殊性。我負(fù)責(zé)的內(nèi)容管理部分。主要是存儲(chǔ)用戶和內(nèi)容的交互數(shù)據(jù)。數(shù)據(jù)量比較大,而且都是新增動(dòng)作,沒有修改。且每條數(shù)據(jù)的字段如果是mysql,會(huì)存在很多varchar長(zhǎng)度超過200,text的字段。所以選擇使用mongodb.
1.首先項(xiàng)目引入依賴
<!--集成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.在具體項(xiàng)目的類中注入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.封裝實(shí)體類,其中Document的注解至關(guān)重要。這個(gè)影響查詢時(shí)能不能查詢到數(shù)據(jù)
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 = "課堂標(biāo)識(shí)", required = true)
private Long virtualClassId;
......
}
5.具體的service操作mongodb庫(kù)
5.1 保存數(shù)據(jù)到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());
//分庫(kù)保存基礎(chǔ)數(shù)據(jù)到mongodb,確保在用戶狀態(tài)先入庫(kù)在入庫(kù)mongodb!
mongoTemplate.insert(homeworkMultimediaDetailDocument, TABLE_NAME);
5.2 mongodb的簡(jiǎn)單查詢
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 復(fù)雜的查詢 多條件,分頁(yè),排序查詢
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);
//首先查詢部分也的總條數(shù)
Long count = mongoTemplate.count(query, HomeworkMultimediaDetailDocument.class);
//導(dǎo)出功能沒有分頁(yè)
if (pageNum != null && pageSize != null) {
PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
query.with(pageRequest);
}
query.with(sort);
//然后分頁(yè),排序查詢具體的list,獲取到本節(jié)的作業(yè)內(nèi)容具體數(shù)據(jù)。
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;
}
以上是具體的生產(chǎn)demo
坑:mongodbTemplate的分頁(yè)第一頁(yè)不是從1開始,而是從0開始。并且新的方法已經(jīng)不是通過new創(chuàng)建對(duì)象。而是這樣:PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);Sort sort = Sort.by(Sort.Direction.DESC, sortField);
經(jīng)驗(yàn)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注解上映射關(guān)系效果一樣。
經(jīng)驗(yàn)2:聚合操作Aggregation完全可以使用Criteria+Query來(lái)代替。最多通過java代碼做些處理。當(dāng)然,如果Aggregation你能正確查詢也很厲害。Query支持單個(gè)字段多種條件,多個(gè)字段排序,分頁(yè)功能。
經(jīng)驗(yàn)3:Query支持的條件查詢一個(gè)字段只能出現(xiàn)一次。像這樣:criteria.and("createTime").gte(startTime).lte(endTime);如果你這樣寫就會(huì)運(yùn)行報(bào)錯(cuò):criteria.and("createTime").gte(startTime); criteria.and("createTime").lte(endTime);
以上便是使用的一些經(jīng)驗(yàn)總結(jié)。希望對(duì)你有所幫助。
————————————————
版權(quán)聲明:本文為CSDN博主「萬(wàn)米高空」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zhanglf02/article/details/114032214
鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布
??????
??長(zhǎng)按上方微信二維碼 2 秒
感謝點(diǎn)贊支持下哈 
