分批次分页查询是一种有效的数据检索策略,它通过将数据分成多个批次来查询和加载,有助于提高应用程序的性能、用户体验和资源利用率。分批次分页查询的作用主要体现在以下几个方面:
- 提高性能:
通过分批次查询,可以减少单次查询对数据库的压力,特别是在处理大量数据时。这有助于避免长时间锁定数据库资源,提高数据库的响应速度和整体性能。
- 优化资源使用:
分批次查询可以更有效地利用网络和服务器资源,尤其是在数据传输和处理过程中。它可以减少一次性传输大量数据所需的带宽和内存消耗。
- 改善用户体验:
在Web应用或用户界面中,分批次分页查询可以提供更流畅的浏览体验。用户可以逐步加载数据,而不是等待所有数据一次性加载完成。
- 增强数据处理能力:
对于需要处理大量数据的应用程序,分批次分页查询允许逐步处理数据,这有助于防止内存溢出或应用程序崩溃。
- 灵活性和可控性:
分批次分页查询提供了更高的灵活性,允许应用程序根据需要加载特定数量的数据,同时也便于实现更复杂的数据处理逻辑,如排序、过滤和聚合。
- 适应不同的业务需求:
不同的业务场景可能需要不同的数据加载策略。分批次分页查询可以根据用户的交互或业务逻辑动态调整数据加载的批次和数量。
- 减轻服务器负担:
在高并发环境下,分批次分页查询可以减轻服务器的负担,避免因同时处理大量请求而导致的服务器过载。
- 实现数据懒加载:
分批次分页查询是实现数据懒加载的一种方式,即仅在需要时才从数据库中检索数据,这样可以提高应用程序的启动速度和运行效率。
以下是分批次分页查询的具体使用:
package xx.xx.xx.main.others.others;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.math.NumberUtils;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xx.xx.xx.demo.dao.CodeTemplateMapper;
import xx.xx.xx.demo.req_dto.CodeTemplateReqDto;
import xx.xx.xx.demo.resp_dto.CodeTemplateRespDto;
import xx.xx.xx.main.MainApplicationTests;
import javax.annotation.Resource;
import java.util.Optional;
/**
* 分批次分页查询测试
*
* @author 付聪
* @time 2024-10-25 10:12:20
*/
public class BatchPagingQueryTest extends MainApplicationTests {
private static final Logger logger = LoggerFactory.getLogger(BatchPagingQueryTest.class);
@Resource
private CodeTemplateMapper codeTemplateMapper;
private void batchPagingQuery(Integer pageNum, Integer pageSize) {
long fullStartTime = System.currentTimeMillis();
pageNum = Optional.ofNullable(pageNum).orElse(1);
pageSize = Optional.ofNullable(pageSize).orElse(10);
// 是否还有下一页
Boolean hasNextPage = Boolean.TRUE;
CodeTemplateReqDto codeTemplateReqDto = new CodeTemplateReqDto();
codeTemplateReqDto.setDelFlag(NumberUtils.INTEGER_ZERO);
while (hasNextPage) {
try {
long everyStartTime = System.currentTimeMillis();
PageHelper.startPage(pageNum, pageSize);
logger.info("在【BatchPagingQueryTest.batchPagingQuery】方法中调用【codeTemplateMapper.selectManyByObject】方法,入参:查询批次是:{}", pageNum);
PageInfo<CodeTemplateRespDto> pageInfo = new PageInfo<>(codeTemplateMapper.selectManyByObject(codeTemplateReqDto));
logger.info("在【BatchPagingQueryTest.batchPagingQuery】方法中调用【codeTemplateMapper.selectManyByObject】方法,出参:pageInfo是:{}", JSONUtil.toJsonStr(pageInfo));
long everyEndTime = System.currentTimeMillis();
logger.info("在【BatchPagingQueryTest.batchPagingQuery】方法中调用【codeTemplateMapper.selectManyByObject】方法,完成进度是:{}/{},当前批次耗时:{}", pageNum, pageInfo.getPages(), DateUtil.formatBetween(everyEndTime - everyStartTime));
// 如果还有下一页,就更新为下一页的页码。
if (pageInfo.isHasNextPage()) {
pageNum++;
} else {
hasNextPage = Boolean.FALSE;
}
} catch (Exception e) {
logger.error("在【BatchPagingQueryTest.batchPagingQuery】方法中执行【分批查询】,出现异常!", e);
throw e;
}
}
long fullEndTime = System.currentTimeMillis();
logger.info("执行【BatchPagingQueryTest.batchPagingQuery】方法,完成!耗时:{}", DateUtil.formatBetween(fullEndTime - fullStartTime));
}
@Test
public void testBatchPagingQuery() {
this.batchPagingQuery(1, 10);
}
}
2024-10-28 09:54:16,519 INFO [main] p.f.c.m.o.o.BatchPagingQueryTest.batchPagingQuery(52): 在【BatchPagingQueryTest.batchPagingQuery】方法中调用【codeTemplateMapper.selectManyByObject】方法,出参:pageInfo是:{"pageNum":17,"pageSize":10,"size":3,"startRow":161,"endRow":163,"pages":17,"prePage":16,"nextPage":0,"isFirstPage":false,"isLastPage":true,"hasPreviousPage":true,"hasNextPage":false,"navigatePages":8,"navigatepageNums":[10,11,12,13,14,15,16,17],"navigateFirstPage":10,"navigateLastPage":17,"total":163,"list":[{"id":5,"remark":"eVz9o27E80","createPersonId":1,"createTime":1690699193000,"updatePersonId":1,"updateTime":1690699193000,"delFlag":0},{"id":4,"remark":"WkWj6iGgdT","createPersonId":1,"createTime":1690699193000,"updatePersonId":1,"updateTime":1690699193000,"delFlag":0},{"id":3,"remark":"VxYpDDvrH6","createPersonId":1,"createTime":1690699193000,"updatePersonId":1,"updateTime":1690699193000,"delFlag":0}]}
2024-10-28 09:54:16,520 INFO [main] p.f.c.m.o.o.BatchPagingQueryTest.batchPagingQuery(54): 在【BatchPagingQueryTest.batchPagingQuery】方法中调用【codeTemplateMapper.selectManyByObject】方法,完成进度是:17/17,当前批次耗时:104毫秒
2024-10-28 09:54:16,520 INFO [main] p.f.c.m.o.o.BatchPagingQueryTest.batchPagingQuery(70): 执行【BatchPagingQueryTest.batchPagingQuery】方法,完成!耗时:2秒866毫秒