目录

  • 它是如何运作的
  • 相关文件
    • 分页运行器.java
    • 架构.sql
    • 数据.sql
  • 示例输出

有时,您需要获取的数据量对于单个行程来说太大了。不要害怕,分页是解决这个问题的一种方法

它是如何运作的#

如果您以前使用过弹簧启动,您可能知道 JPA 包含开箱即用的分页支持。虽然这很好,但在某些情况下(比如我最近在工作中遇到的那个),你正在使用原始的、复杂的SQL,但你仍然需要一些方法来做分页。

幸运的是,通过一些尝试和错误,以及一堆谷歌搜索,我制定了一个解决方案。

如果遇到问题,请在 GitHub 存储库中签出整个项目。

相关文件#

分页运行器.java#

文件: src/main/java/com/示例/演示/分页运行器.java

// package and import lines removed for brevity 
@Component
public class PaginationRunner implements ApplicationRunner {Logger logger = LoggerFactory.getLogger(PaginationRunner.class);/**  * The pageSize is configurable. We default it to 5 here.  * You can override it in the src/main/resources/application.properties file by setting pagination_runner.page_size.  * Or, via env var by setting PAGINATION_RUNNER_PAGE_SIZE.  */@Value("${pagination_runner.page_size:5}")private int pageSize;/**  * The jdbcTemplate uses the default data source. Which, in this demo, is the in-memory H2 database.  */@Autowiredprivate JdbcTemplate jdbcTemplate;/**  * This class implements ApplicationRunner.  * So, this component will run after the Spring Application Context is initialized.  */@Overridepublic void run(ApplicationArguments args) throws Exception {logger.info("Starting PaginationRunner");loopThroughThePages();logger.info("Finished PaginationRunner");}/**  * Loop through the pages until you encounter an empty page.  */private void loopThroughThePages() {Pageable pageable = PageRequest.of(0, pageSize);Page<Map<String, Object>> page = findAll(pageable);while (!page.isEmpty()) {logProgress(pageable, page);page.stream().forEach(this::handleRow);pageable = pageable.next();page = findAll(pageable);}}/**  * Find all the rows.  * You _could_ create the query using LIMIT and OFFSET...  * But, I went with a plain WHERE clause that selects a range of IDs because it's faster.  */private Page<Map<String, Object>> findAll(Pageable pageable) {long startId = pageable.getOffset();long endId = startId + pageable.getPageSize();String sql = String.format("SELECT * FROM word WHERE id > %s AND id <= %s",startId,endId);logger.info("findAll sql: {}", sql);List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);long total = countAll();return new PageImpl<>(rows, pageable, total);}/**  * Count all the rows.  */private long countAll() {String sql = "SELECT COUNT(*) FROM word";logger.info("countAll sql: {}", sql);return jdbcTemplate.queryForObject(sql, Long.class);}/**  * Log the progress.  * You'll thank yourself for this, especially if the "job" is long-running.  */private void logProgress(Pageable pageable, Page<Map<String, Object>> page) {int currentPage = pageable.getPageNumber() + 1;int totalPages = page.getTotalPages();int currentRowCount = page.getNumberOfElements();long totalRowCount = page.getTotalElements();logger.info("On page {} of {}. Rows in page: {}. Total rows: {}",currentPage, totalPages, currentRowCount, totalRowCount);}/**  * Actually do something with each row.  * In this demo, I'm just logging the row.  * In a real scenario, maybe you're building up a bulk request to send somewhere else, etc.  */private void handleRow(Map<String, Object> row) {logger.info(row.toString());}}

架构.sql#

File: src/main/resources/schema.sql

-- When using the in-memory H2 database, this is how the schema is defined. 
CREATE TABLE word (id INT AUTO_INCREMENT PRIMARY KEY,word CHARACTER VARYING
);

数据.sql#

文件:主/资源/数据.sql

-- When using the in-memory H2 database, this is how the data is seeded. -- I got this data by grepping for words starting with "b" in the built-in Mac dictionary at /usr/share/dict/words. 
INSERT INTO word (word) VALUES ('babblesome');
INSERT INTO word (word) VALUES ('babbling');
INSERT INTO word (word) VALUES ('babblingly');
INSERT INTO word (word) VALUES ('babblish');
INSERT INTO word (word) VALUES ('babblishly');
INSERT INTO word (word) VALUES ('babbly');
INSERT INTO word (word) VALUES ('babby');
INSERT INTO word (word) VALUES ('babe');
INSERT INTO word (word) VALUES ('babehood');
INSERT INTO word (word) VALUES ('babelet');
INSERT INTO word (word) VALUES ('babelike');

示例输出#

您可以通过运行应用程序来查看此内容:./gradlew bootRun

Starting PaginationRunner
findAll sql: SELECT * FROM word WHERE id > 0 AND id <= 5
countAll sql: SELECT COUNT(*) FROM word
On page 1 of 3. Rows in page: 5. Total rows: 11
{ID=1, WORD=babblesome}
{ID=2, WORD=babbling}
{ID=3, WORD=babblingly}
{ID=4, WORD=babblish}
{ID=5, WORD=babblishly}
findAll sql: SELECT * FROM word WHERE id > 5 AND id <= 10
countAll sql: SELECT COUNT(*) FROM word
On page 2 of 3. Rows in page: 5. Total rows: 11
{ID=6, WORD=babbly}
{ID=7, WORD=babby}
{ID=8, WORD=babe}
{ID=9, WORD=babehood}
{ID=10, WORD=babelet}
findAll sql: SELECT * FROM word WHERE id > 10 AND id <= 15
countAll sql: SELECT COUNT(*) FROM word
On page 3 of 3. Rows in page: 1. Total rows: 11
{ID=11, WORD=babelike}
findAll sql: SELECT * FROM word WHERE id > 15 AND id <= 20
countAll sql: SELECT COUNT(*) FROM word
Finished PaginationRunner

Spring Boot JdbcTemplate SQL 查询分页相关推荐

  1. 前端Vue+ElementUI的Pagination分页组件实现分页展示 后端Spring Boot +Mybatis Plus实现分页接口

    前端Vue+ElementUI的Pagination分页组件实现分页展示 & 后端Spring Boot +Mybatis Plus实现分页接口 很久没有更新博客了,主要原因是博主一直在补充自 ...

  2. Spring Boot JPA的查询语句

    文章目录 准备工作 Containing, Contains, IsContaining 和 Like StartsWith EndsWith 大小写不敏感 Not @Query Spring Boo ...

  3. Spring Boot java.sql.SQLSyntaxErrorException: Table ‘mydb.table_name‘ doesn‘t exist

    我是强哥,一个在互联网苟且的男人 Spring Boot java.sql.SQLSyntaxErrorException: Table 'mydb.table_name' doesn't exist ...

  4. Spring Boot系列六 Spring boot集成mybatis、分页插件pagehelper

    1. 概述 本文的内容包括如下内容: Spring Boot集成mybatis Spring Boot集成pagehelper分页插件,定义分页的相关类 实现工具类:model转dto,实现数据层和传 ...

  5. spring boot+mybatis+thymeleaf+pagehelper分页插件实现分页功能

    文章目录 前言 正文 业务场景 后端 pom.xml application.yml 实体类video.java和User.java----映射VideoMapper.xml----VideoMapp ...

  6. Spring Boot:实现MyBatis分页

    综合概述 想必大家都有过这样的体验,在使用Mybatis时,最头痛的就是写分页了,需要先写一个查询count的select语句,然后再写一个真正分页查询的语句,当查询条件多了之后,会发现真的不想花双倍 ...

  7. Spring Boot——一种包含分页和排序参数的接收方法DEMO

    Maven 主要Maven依赖 <dependency><groupId>org.springframework.boot</groupId><artifac ...

  8. Spring Boot+JPA 有查询条件的查询

    本篇介绍使用JPA 的条件查询, 关于JPA基本查询可以参考: Spring Boot+JPA 查询数据方式与代码演示 不安全的查询 在开发时, 为了简便, 习惯会拼接Where子句的查询条件, 查询 ...

  9. spring boot使用mybatis进行分页实战

    文章目录 环境介绍 添加依赖 application.properties配置 控制器演示代码 浏览器访问结果 前几天研究了Spring Boot中访问关系型数据库的三个框架,其中mybatis使用最 ...

最新文章

  1. 第二阶段 铁大Facebook——十天冲刺(七)
  2. 书山有径——走进清华大学图书馆
  3. 二分查找--AVL查找树
  4. Matlab画图小结(二)
  5. 2019 ICPC World Finals Problem J. Miniature Golf
  6. Zookeepr 如何进行权限控制?
  7. 懒人修仙传ce修改方法_专访|《凡人修仙传》原著作者忘语:“韩老魔”原型是我...
  8. 单片机加减法计算器_单片机简易加法计算器程序
  9. Apache Hadoop 源码阅读(陆续更新)
  10. 纳尼?你居然还在使用fastjson,性能太差了,这个新出的秒杀fastjson
  11. Ubuntu 19 ✖64安装GDAL
  12. less混合 + less计算
  13. 租服务器的 直连100m是啥,如何知道我的服务器带宽是独享10M或者100M?
  14. 多用途手机登录页面模板
  15. VR时代的媒介——虚拟的真实感就是真实
  16. vue项目手机端适配
  17. 【166】VS2022调试通过海康人脸抓拍SDK的C++代码
  18. Bing(必应)搜索,为什么用户越来越多?
  19. JS File 和 Blob 是什么
  20. debian 安装firefox 最新版

热门文章

  1. Antd+Vue2实现动态编辑表格
  2. trello清单(二)
  3. qq空间留言板删除 php,PHP实现QQ空间自动回复说说的方法
  4. Move!Move!!Move!!!
  5. 我的病毒代码之bat文件 win10系统版
  6. 【数据架构】什么是运营报告?
  7. js中 try{...} 意思
  8. About 7.17 This Week
  9. tcpdump 命令使用教程
  10. 【图像处理】RGB、YUV (YCbCr) 图像表示详解