SpringBoot系列(19):SpringBoot整合MongoDB實(shí)戰(zhàn)二之刪除與分頁(yè)查詢

作者: 修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。


摘要:文檔數(shù)據(jù)庫(kù)中間件MongoDB的強(qiáng)大之處在于其可以存儲(chǔ)大批量、海量的數(shù)據(jù)并可實(shí)現(xiàn)快速、高效、穩(wěn)定的查詢功能(據(jù)說(shuō)千萬(wàn)級(jí)、億級(jí)別的數(shù)據(jù)查詢只需要幾秒),其底層是采用“文檔Document”的形式、Json格式的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)的,在大數(shù)據(jù)量查詢的場(chǎng)景下相對(duì)于關(guān)系型數(shù)據(jù)庫(kù)如Mysql而言,效率將顯著提升,本文我們將模擬在大數(shù)據(jù)量的場(chǎng)景下實(shí)現(xiàn)數(shù)據(jù)的分頁(yè)查詢與刪除功能。

內(nèi)容:在上一篇文章中我們簡(jiǎn)要介紹了NoSQL領(lǐng)域中鼎鼎大名的文檔型數(shù)據(jù)庫(kù)中間件MongoDB,并基于Spring Boot2.0搭建的企業(yè)級(jí)項(xiàng)目整合了MongoDB服務(wù)實(shí)戰(zhàn)了“用戶模塊User”最基本的新增、批量新增、修改與簡(jiǎn)單的查詢。本文我們將繼續(xù)介紹其剩下的刪除功能和“大數(shù)據(jù)量”的場(chǎng)景下其分頁(yè)查詢功能的實(shí)現(xiàn)!

(1)我們直接貼出“刪除”功能代碼的實(shí)現(xiàn)吧:

    //TODO:刪除
@Transactional(rollbackFor = Exception.class)
public void delete(final Integer id) throws Exception{
int res=userMapper.deleteByPrimaryKey(id);
if (res>0){
Query query=Query.query(Criteria.where("id").is(id));
mongoTemplate.remove(query,MongoUser.class);
}
}

直接調(diào)用mongoTemplate的remove方法即可實(shí)現(xiàn)!之后,直接寫(xiě)個(gè)Java單元測(cè)試用例即可查看其最終的執(zhí)行效果,如下所示:  

    @Test
public void method5() throws Exception{
log.info("---單元測(cè)試5-刪除---");

final Integer id=343686;
mongoUserRepository.delete(id);

MongoUser entity=mongoUserRepository.queryById(id);
log.info("---根據(jù)主鍵id查詢,結(jié)果={}---",entity);
}

點(diǎn)擊運(yùn)行之后,通過(guò)Navicat 跟 Robo 3T查看該條數(shù)據(jù),會(huì)發(fā)現(xiàn)該條記錄已經(jīng)不存在了!

(2)緊接著我們寫(xiě)個(gè)多線程、往MongoDb批量插入大批量的數(shù)據(jù),然后我們一起來(lái)體驗(yàn)一下大數(shù)據(jù)量場(chǎng)景下“分頁(yè)查詢”功能的實(shí)現(xiàn)。這其中“多線程插入大批量的數(shù)據(jù)” 的過(guò)程在這里Debug就不貼出來(lái)了,各位小伙伴可以直接參考我之前寫(xiě)的文章“線程池-多線程批量插入大批量的數(shù)據(jù)”(或者check出源代碼直接查看其實(shí)現(xiàn)即可)!如下圖所示,我們往其中插入了343686條記錄:


之后,我們借助MongoTemplate其中的skip和limit方法實(shí)現(xiàn)其中的分頁(yè)功能,其中,我們實(shí)現(xiàn)了兩種類型的分頁(yè)查詢功能,一種是直接limit pageStart,pageSize,另一種是加上某種排序的limit,即order by xxx desc limit pageStart,pageSize。完整的源代碼實(shí)現(xiàn)如下所示:

    //TODO:分頁(yè)查詢
public Map<String,Object> queryPage(Integer pageNo, final Integer pageSize) throws Exception{
Map<String,Object> resMap= Maps.newHashMap();
if (pageNo<=0){
pageNo=1;
}
Integer pageStart=(pageNo-1)*pageSize;

//TODO:正常不帶條件的分頁(yè)
//Query query=Query.query(Criteria.where("isActive").is(1)).skip(pageStart).limit(pageSize);
//return mongoTemplate.find(query,MongoUser.class);


//TODO:正常帶條件的分頁(yè)-按照code倒序
Query query=Query.query(Criteria.where("isActive").is(1)).skip(pageStart).limit(pageSize)
.with(Sort.by(Sort.Direction.DESC,"code"));
//TODO:查詢出目前MongoDB中該集合“mongoUser”總的數(shù)據(jù)條目
Long total=mongoTemplate.count(query,MongoUser.class);
List<MongoUser> list=mongoTemplate.find(query,MongoUser.class);

resMap.put("total",total);
resMap.put("list",list);

return resMap;
}

在上述分頁(yè)查詢中,我們還通過(guò)調(diào)用mongoTemplate的count方法實(shí)現(xiàn)查詢某個(gè)集合下的總的數(shù)據(jù)條目total,這在“分頁(yè)”的業(yè)務(wù)場(chǎng)景中是必需的(用于計(jì)算是否還有下一頁(yè)以及下一頁(yè)的具體頁(yè)碼啥的?。?/span>

最后,我們寫(xiě)個(gè)Java單元測(cè)試方法,通過(guò)傳入不同的頁(yè)碼pageNo,以及頁(yè)數(shù)據(jù)量pageSize,可以得到對(duì)應(yīng)的實(shí)際的數(shù)據(jù)條目,如下所示:

     @Test
public void method6() throws Exception{
log.info("---單元測(cè)試6-分頁(yè)查詢---");
final Integer pageSize=10;

Integer pageNo=1;
Map<String,Object> resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分頁(yè)查詢pageNo={} pageSize={} 結(jié)果={}\n\n",pageNo,pageSize,resMap);

pageNo=2;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分頁(yè)查詢pageNo={} pageSize={} 結(jié)果={}\n\n",pageNo,pageSize,resMap);

pageNo=3;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分頁(yè)查詢pageNo={} pageSize={} 結(jié)果={}\n\n",pageNo,pageSize,resMap);

pageNo=800;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分頁(yè)查詢pageNo={} pageSize={} 結(jié)果={}\n\n",pageNo,pageSize,resMap);

pageNo=1000;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分頁(yè)查詢pageNo={} pageSize={} 結(jié)果={}\n\n",pageNo,pageSize,resMap);

pageNo=2000;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分頁(yè)查詢pageNo={} pageSize={} 結(jié)果={}\n\n",pageNo,pageSize,resMap);
}


運(yùn)行效果如下所示:


至此,關(guān)于文檔型數(shù)據(jù)庫(kù)中間件MongoDB的常見(jiàn)應(yīng)用我們介紹到這里了!當(dāng)然啦,在實(shí)際的企業(yè)級(jí)應(yīng)用開(kāi)發(fā)中,MongoDB在分片、集群、聚合查詢、索引(單Field與組合Field索引)也有其施展的空間,在這里Debug就不往下繼續(xù)分享了,感興趣的小伙伴可以來(lái)此繼續(xù)深造:http://www.mongoing.com/docs/sharding.html ,有機(jī)會(huì),Debug會(huì)錄制一套完備的課程分享介紹MongoDB的技術(shù)棧與實(shí)際應(yīng)用場(chǎng)景!

好了,本篇文章我們就介紹到這里了,其他相關(guān)的技術(shù),感興趣的小伙伴可以關(guān)注底部Debug的技術(shù)公眾號(hào),或者加Debug的微信,拉你進(jìn)“微信版”的真正技術(shù)交流群!一起學(xué)習(xí)、共同成長(zhǎng)!

補(bǔ)充:

1、本文涉及到的相關(guān)的源代碼可以到此地址,check出來(lái)進(jìn)行查看學(xué)習(xí):

https://gitee.com/steadyjack/SpringBootTechnology

2、最近Debug發(fā)布了幾門(mén)重量級(jí)的課程,感興趣的小伙伴可以前往觀看學(xué)習(xí):
(1) 緩存中間件Redis技術(shù)入門(mén)與應(yīng)用場(chǎng)景實(shí)戰(zhàn)(SpringBoot2.x + 搶紅包系統(tǒng)設(shè)計(jì)與實(shí)戰(zhàn)) 
https://www.fightjava.com/web/index/course/detail/12

(2)  企業(yè)權(quán)限管理平臺(tái)(SpringBoot2.0+Shiro+Vue+Mybatis) 
https://www.fightjava.com/web/index/course/detail/8

3、關(guān)注一下Debug的技術(shù)微信公眾號(hào),最新的技術(shù)文章、課程以及技術(shù)專欄將會(huì)第一時(shí)間在公眾號(hào)發(fā)布哦!