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

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


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

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

(1)我們直接貼出“刪除”功能代碼的實現(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方法即可實現(xiàn)!之后,直接寫個Java單元測試用例即可查看其最終的執(zhí)行效果,如下所示:  

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

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

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

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

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


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

    //TODO:分頁查詢
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:正常不帶條件的分頁
//Query query=Query.query(Criteria.where("isActive").is(1)).skip(pageStart).limit(pageSize);
//return mongoTemplate.find(query,MongoUser.class);


//TODO:正常帶條件的分頁-按照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;
}

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

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

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

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

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

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

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

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

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


運行效果如下所示:


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

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

補(bǔ)充:

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

https://gitee.com/steadyjack/SpringBootTechnology

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

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

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