SpringBoot系列(19):SpringBoot整合MongoDB实战二之删除与分页查询
作者:
修罗debug
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
摘要:文档数据库中间件MongoDB的强大之处在于其可以存储大批量、海量的数据并可实现快速、高效、稳定的查询功能(据说千万级、亿级别的数据查询只需要几秒),其底层是采用“文档Document”的形式、Json格式的数据结构来存储数据的,在大数据量查询的场景下相对于关系型数据库如Mysql而言,效率将显著提升,本文我们将模拟在大数据量的场景下实现数据的分页查询与删除功能。
内容:在上一篇文章中我们简要介绍了NoSQL领域中鼎鼎大名的文档型数据库中间件MongoDB,并基于Spring Boot2.0搭建的企业级项目整合了MongoDB服务实战了“用户模块User”最基本的新增、批量新增、修改与简单的查询。本文我们将继续介绍其剩下的删除功能和“大数据量”的场景下其分页查询功能的实现!
(1)我们直接贴出“删除”功能代码的实现吧:
//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);
}
}
直接调用mongoTemplate的remove方法即可实现!之后,直接写个Java单元测试用例即可查看其最终的执行效果,如下所示:
@Test
public void method5() throws Exception{
log.info("---单元测试5-删除---");
final Integer id=343686;
mongoUserRepository.delete(id);
MongoUser entity=mongoUserRepository.queryById(id);
log.info("---根据主键id查询,结果={}---",entity);
}
点击运行之后,通过Navicat 跟 Robo 3T查看该条数据,会发现该条记录已经不存在了!
(2)紧接着我们写个多线程、往MongoDb批量插入大批量的数据,然后我们一起来体验一下大数据量场景下“分页查询”功能的实现。这其中“多线程插入大批量的数据” 的过程在这里Debug就不贴出来了,各位小伙伴可以直接参考我之前写的文章“线程池-多线程批量插入大批量的数据”(或者check出源代码直接查看其实现即可)!如下图所示,我们往其中插入了343686条记录:
之后,我们借助MongoTemplate其中的skip和limit方法实现其中的分页功能,其中,我们实现了两种类型的分页查询功能,一种是直接limit pageStart,pageSize,另一种是加上某种排序的limit,即order by xxx desc limit pageStart,pageSize。完整的源代码实现如下所示:
//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”总的数据条目
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;
}
在上述分页查询中,我们还通过调用mongoTemplate的count方法实现查询某个集合下的总的数据条目total,这在“分页”的业务场景中是必需的(用于计算是否还有下一页以及下一页的具体页码啥的!)
最后,我们写个Java单元测试方法,通过传入不同的页码pageNo,以及页数据量pageSize,可以得到对应的实际的数据条目,如下所示:
@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={} 结果={}\n\n",pageNo,pageSize,resMap);
pageNo=2;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分页查询pageNo={} pageSize={} 结果={}\n\n",pageNo,pageSize,resMap);
pageNo=3;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分页查询pageNo={} pageSize={} 结果={}\n\n",pageNo,pageSize,resMap);
pageNo=800;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分页查询pageNo={} pageSize={} 结果={}\n\n",pageNo,pageSize,resMap);
pageNo=1000;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分页查询pageNo={} pageSize={} 结果={}\n\n",pageNo,pageSize,resMap);
pageNo=2000;
resMap=mongoUserRepository.queryPage(pageNo,pageSize);
log.info("---分页查询pageNo={} pageSize={} 结果={}\n\n",pageNo,pageSize,resMap);
}
运行效果如下所示:
至此,关于文档型数据库中间件MongoDB的常见应用我们介绍到这里了!当然啦,在实际的企业级应用开发中,MongoDB在分片、集群、聚合查询、索引(单Field与组合Field索引)也有其施展的空间,在这里Debug就不往下继续分享了,感兴趣的小伙伴可以来此继续深造:http://www.mongoing.com/docs/sharding.html ,有机会,Debug会录制一套完备的课程分享介绍MongoDB的技术栈与实际应用场景!
好了,本篇文章我们就介绍到这里了,其他相关的技术,感兴趣的小伙伴可以关注底部Debug的技术公众号,或者加Debug的微信,拉你进“微信版”的真正技术交流群!一起学习、共同成长!
补充:
1、本文涉及到的相关的源代码可以到此地址,check出来进行查看学习:
https://gitee.com/steadyjack/SpringBootTechnology
2、最近Debug发布了几门重量级的课程,感兴趣的小伙伴可以前往观看学习:
(1) 缓存中间件Redis技术入门与应用场景实战(SpringBoot2.x + 抢红包系统设计与实战)
https://www.fightjava.com/web/index/course/detail/12
(2) 企业权限管理平台(SpringBoot2.0+Shiro+Vue+Mybatis)
https://www.fightjava.com/web/index/course/detail/8
3、关注一下Debug的技术微信公众号,最新的技术文章、课程以及技术专栏将会第一时间在公众号发布哦!