Spring Data JPA 中的分页实现:从 BasePage 到 Pageable
文章目录
- Spring Data JPA 中的分页实现:从 BasePage 到 Pageable
- 背景:为什么需要分页?
- 认识 BasePage 类
- 深入 toPageable() 方法
- 1. 处理页码和页面大小
- 2. 处理排序方向
- 3. 处理排序字段
- 4. 生成 Pageable 对象
- 实战:如何使用 BasePage
- 1. 前端请求
- 2. 后端控制器
- 3. 查询数据库
- 4. 返回结果
- 小结
Spring Data JPA 中的分页实现:从 BasePage 到 Pageable
在现代 Web 开发中,分页是一个常见的需求。无论是展示商品列表、文章列表还是用户数据,当数据量较大时,分页不仅能提升用户体验,还能减轻服务器的压力。如果你使用的是 Spring Boot 和 Spring Data JPA,那么分页功能已经内置其中,开发者只需简单配置即可实现。今天,我们通过一个简单的 BasePage 类,来看看如何优雅地实现分页和排序功能。
背景:为什么需要分页?
假设你正在开发一个电商平台,数据库中有成千上万的商品记录。如果一次性将所有数据返回给前端,不仅加载速度会变慢,用户也很难从中找到所需信息。这时,分页就派上用场了:每页显示固定数量的记录(比如 10 条),用户可以通过翻页操作逐步浏览。
Spring Data JPA 提供了一个强大的接口 Pageable,它封装了分页和排序的逻辑。通过 Pageable,我们可以轻松实现“第几页”、“每页几条”以及“按什么字段排序”的功能。而今天的主角——BasePage 类,就是一个自定义的分页模型,通过它我们可以将前端传入的分页参数转换为 Pageable 对象。
认识 BasePage 类
BasePage 是一个简单的分页模型类,包含了分页和排序的核心属性。以下是它的代码结构:
public class BasePage {@ApiModelProperty("页码")Integer page;@ApiModelProperty("页大小")Integer size;@ApiModelProperty(value = "排序规则(ASC/DESC)", allowableValues = "ASC,DESC")String direction;@ApiModelProperty("排序字段")String[] properties;// 构造函数、getter 和 setter 略public Pageable toPageable() {page = page != null ? page : 0;size = size != null ? size : 9999;Sort.Direction dir = Sort.Direction.fromOptionalString(this.direction).orElse(Sort.Direction.DESC);Sort sort = (properties != null && properties.length > 0) ? Sort.by(dir, properties) : Sort.by(dir, "createdDate");return PageRequest.of(page, size, sort);}
}
这个类包含了四个关键属性:
page:页码,表示当前是第几页。size:每页的大小,表示每页显示多少条记录。direction:排序方向,可以是"ASC"(升序)或"DESC"(降序)。properties:排序字段,表示按哪些字段排序。
而 toPageable() 方法则是这个类的核心,它将这些属性转化为 Spring Data JPA 所需的 Pageable 对象。
深入 toPageable() 方法
让我们一步步拆解 toPageable() 方法,看看它是如何工作的:
1. 处理页码和页面大小
page = page != null ? page : 0;
size = size != null ? size : 9999;
- 如果
page未设置(null),默认值为 0,表示第一页(Spring Data 的页码从 0 开始)。 - 如果
size未设置,默认值为 9999。这是一个很大的数字,通常是为了在未指定页面大小时尽量返回所有数据。不过在实际应用中,建议根据业务需求设置一个合理的默认值,比如 10 或 20。
2. 处理排序方向
Sort.Direction dir = Sort.Direction.fromOptionalString(this.direction).orElse(Sort.Direction.DESC);
Sort.Direction是 Spring Data 的枚举类,表示排序方向。fromOptionalString(this.direction)尝试将direction(如 “ASC” 或 “DESC”)解析为Sort.Direction类型。- 如果解析失败或
direction为null,则使用默认值Sort.Direction.DESC(降序)。
3. 处理排序字段
Sort sort = (properties != null && properties.length > 0) ? Sort.by(dir, properties) : Sort.by(dir, "createdDate");
- 如果
properties不为空,则按指定的字段排序。 - 如果
properties为空或未设置,则默认按"createdDate"(创建时间)字段排序。 Sort.by(dir, properties)创建了一个Sort对象,封装了排序方向和字段。
4. 生成 Pageable 对象
return PageRequest.of(page, size, sort);
- 使用
PageRequest.of()方法,将页码、页面大小和排序规则组合成一个Pageable对象。 - 这个对象可以直接传递给 Spring Data 的查询方法。
实战:如何使用 BasePage
假设我们有一个商品管理的接口,需要支持分页和排序。以下是实现步骤:
1. 前端请求
前端发送一个 HTTP 请求,例如:
GET /products?page=1&size=10&direction=ASC&properties=price
page=1:请求第 2 页(从 0 开始计数)。size=10:每页 10 条记录。direction=ASC:按升序排序。properties=price:按价格排序。
2. 后端控制器
在 Spring Boot 的控制器中接收参数并构造 BasePage:
@RestController
@RequestMapping("/products")
public class ProductController {@Autowiredprivate ProductRepository productRepository;@GetMappingpublic Page<Product> getProducts(@RequestParam(required = false) Integer page,@RequestParam(required = false) Integer size,@RequestParam(required = false) String direction,@RequestParam(required = false) String[] properties) {BasePage basePage = new BasePage();basePage.setPage(page);basePage.setSize(size);basePage.setDirection(direction);basePage.setProperties(properties);Pageable pageable = basePage.toPageable();return productRepository.findAll(pageable);}
}
3. 查询数据库
ProductRepository 是一个 Spring Data JPA 提供的接口:
public interface ProductRepository extends JpaRepository<Product, Long> {
}
调用 findAll(Pageable pageable) 方法后,Spring Data 会自动生成 SQL 查询,返回分页后的结果。
4. 返回结果
最终返回的 JSON 可能长这样:
{"content": [{"id": 1, "name": "商品A", "price": 10.0},{"id": 2, "name": "商品B", "price": 15.0},...],"totalElements": 50,"totalPages": 5,"number": 1,"size": 10
}
小结
通过 BasePage 和 toPageable() 方法,我们实现了一个简单而灵活的分页模型。它的优点在于:
- 简单易用:只需设置几个属性,就能生成
Pageable对象。 - 默认值友好:未设置的参数有合理的默认值,避免空指针问题。
- 支持排序:灵活指定排序字段和方向,满足复杂需求。
当然,实际开发中还可以根据需求扩展 BasePage,比如添加参数验证、支持多字段排序等。Spring Data JPA 的分页功能非常强大,配合自定义模型类,可以让代码更优雅、更易维护。
如果你也正在为分页功能苦恼,不妨试试这种方式吧!有什么问题或想法,欢迎在评论区交流。

相关文章:
Spring Data JPA 中的分页实现:从 BasePage 到 Pageable
文章目录 Spring Data JPA 中的分页实现:从 BasePage 到 Pageable背景:为什么需要分页?认识 BasePage 类深入 toPageable() 方法1. 处理页码和页面大小2. 处理排序方向3. 处理排序字段4. 生成 Pageable 对象 实战:如何使用 BasePa…...
自然语言处理NLP入门 -- 第八节OpenAI GPT 在 NLP 任务中的应用
在前面的学习中,我们已经了解了如何使用一些经典的方法和模型来处理自然语言任务,如文本分类、命名实体识别等。但当我们需要更强的语言生成能力时,往往会求助于更先进的预训练语言模型。OpenAI 旗下的 GPT 系列模型(如 GPT-3、GP…...
HTML:自闭合标签简单介绍
1. 什么是自结束标签? 定义:自结束标签(Self-closing Tag)是指 不需要单独结束标签 的 HTML 标签,它们通过自身的语法结构闭合。语法形式: 在 HTML5 中:直接写作 <tag>,例如 …...
智能家居遥控革命!昂瑞微HS6621EM:用「芯」定义AIoT时代的语音交互标杆
AIoT爆发期,遥控器为何成为智能家居的「隐形战场」? 随着Meta、苹果等巨头加速布局空间计算,智能家居生态正从「单一设备联网」向「全场景无感交互」跃迁。作为高频使用的入口设备,语音遥控器的性能直接决定用户体验天花板。昂瑞微…...
AI学习第七天
数组:基础概念、存储特性及力扣实战应用 在计算机科学与数学的广袤领域中,数组作为一种极为重要的数据结构,发挥着不可或缺的作用。它就像一个有序的 “数据仓库”,能高效地存储和管理大量数据。接下来,让我们深入了解…...
Grafana使用日志7--开启Sigv4
背景 在Grafana中,有些data source是需要开启sigv4认证的,例如OpenSearch,这个配置项默认是关闭的,这里我们介绍一下怎么开启 步骤 传统方式 如果我们想在Grafana中开启sigv4认证,我们需要在grafana.ini中修改一个…...
【Redis】Redis 入门
借鉴枫枫知道 一、连接 redis 1.1 命令行连接 // 完整的命令 redis-cli -h 127.0.0.1 -p 6379 -a password// 简写 redis-cli// 认证,进行redis之后 auth password1.2 go 代码连接 package mainimport ("fmt""github.com/go-redis/redis" …...
一文了解:部署 Deepseek 各版本的硬件要求
很多朋友在咨询关于 DeepSeek 模型部署所需硬件资源的需求,最近自己实践了一部分,部分信息是通过各渠道收集整理,so 仅供参考。 言归正转,大家都知道,DeepSeek 模型的性能在很大程度上取决于它运行的硬件。我们先看一下…...
15.14 QLoRA量化低秩适配微调:华盛顿大学的显存优化革命
QLoRA量化低秩适配微调:华盛顿大学的显存优化革命 一、技术架构解析 #mermaid-svg-Rkx3w3RQJ1e7odbb {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Rkx3w3RQJ1e7odbb .error-icon{fill:#552222;}#mermaid-svg-Rk…...
软件工程复试专业课-能力成熟度模型CMM
CMM CMM概念CMM的核心CMM来由CMM的目的成熟度等级初始级可重复级已定义级已管理级优化级 CMM概念 即能力成熟度模型,是对于软件组织在定义、实施、度量、控制和改善其软件过程的实践中各个发展阶段的描述。 CMM是改进软件过程的有效策略。它的基本思想是࿰…...
Dify使用和入门
第一步:了解 Dify 在开始之前,先简单了解一下 Dify 是什么: Dify 是一个开源的 LLM 应用开发平台,专注于帮助开发者快速构建生产级的生成式 AI 应用。它支持知识库集成、RAG(检索增强生成)技术、复杂工作…...
Mercury、LLaDA 扩散大语言模型
LLaDA 参考: https://github.com/ML-GSAI/LLaDA https://ml-gsai.github.io/LLaDA-demo/ 在线demo: https://huggingface.co/spaces/multimodalart/LLaDA Mercury 在线demo: https://chat.inceptionlabs.ai/ 速度很快生成...
Windows 图形显示驱动开发-WDDM 3.2-自动显示切换(十二)
API 更改 ADS 功能增加了以下公共 API 功能: 枚举系统中的多路复用器设备。查询有关多路复用器的信息,例如,它连接了哪些目标,以及当前切换到哪个目标。触发多路复用器切换。如何检测多路复用器是否已切换。 枚举系统中的多路复…...
Windows环境下SuperMapGIS 11i 使用达梦数据库
1. 环境介绍: 1.1. 操作系统: windows server 2019 1.2. GIS 软件: 1.2.1. GIS 桌面 supermap-idesktopx-11.3.0-windows-x64-bin 下载链接:SuperMap技术资源中心|为您提供全面的在线技术服务 安装教程:绿色版&…...
Claude 3.7 Sonnet深度解析:混合推理模型如何重塑AI编程能力
引言 2025年2月25日,人工智能领域领先企业Anthropic正式发布了新一代大语言模型Claude 3.7 Sonnet。作为全球首个混合推理AI模型,Claude 3.7 Sonnet在编程开发、逻辑推理以及任务处理效率等方面实现了突破性进展。本文将从核心特性、性能评测、竞品对比…...
IP属地是通过卫星定位的吗?如何保护用户隐私
在数字时代,网络空间成为了人们日常生活不可或缺的一部分。随着社交媒体、在线服务等平台的兴起,用户IP属地信息的重要性日益凸显。然而,关于IP属地是如何确定的,尤其是是否通过卫星定位这一问题,却常常引发公众的疑问…...
金融赋能绍兴纺织 民生银行助力外贸中小微企业“走出去”
在浙江绍兴,纺织业作为一张熠熠生辉的产业名片,承载着深厚的历史底蕴与蓬勃的发展活力。这里依傍长三角经济圈,交通网络纵横交错,将原材料产地与广阔市场紧密相连;产业集群高度成熟,上下游产业链完备&#…...
标记符号“<”和“>”符号被称为“尖括号”或“角括号”
你提到的“<”和“>”符号被称为“尖括号”或“角括号”。它们常用于编程语言中表示类型参数(如泛型)、HTML标签(如<div>)、数学中的不等式(如< 5)等。 好的,我来用通俗的方式解…...
一键部署DeepSeek
腾讯Cloud Studio提供DeepSeek一键部署功能,0行代码,秒级部署使用! 重点是每月免费提供10000分钟! 不用等待模型下载,创建即可使用。 内置 Ollama、DeepSeek-R1 1.5B、7B、8B、14B 及 32B 模型。 热门模板 AI模板 前…...
科普:ROC AUC与PR AUC
在评价二分类模型性能时,有许多评价指标,其中,有一对是用面积AUC(Area Under the Curve)做评价的:ROC AUC与PR AUC 本文我们对ROC AUC与PR AUC进行多维度对比分析: 一、定义与核心原理 维度RO…...
自动化测试无法启动(java.net.SocketException)
在运行测试代码,对浏览器进行自动化操作时,遇到了以下问题,添加依赖,编写了测试代码,但是程序无法运行 这个有两种原因(我使用的是谷歌浏览器): 网络问题: 因为需要从GitHub上下载对应包,所以有时候可能会出现网络问题,这个时候可以打开VPN之后,重新对程序进行启动 浏览器版本…...
大白话解释xxl-job是什么 有什么用 怎么用
XXL-JOB是什么? XXL-JOB就像快递公司的“总调度中心”,专门帮你的程序在不同服务器之间协调和执行定时任务。比如你有个电商系统,每天凌晨要统计订单数据、每小时要发促销短信,这些定时任务交给XXL-JOB来统一管理,它能…...
STM32G473VET6 在 Keil MDK 下手动移植 FreeRTOS 指南
下面将详细介绍如何在 Keil MDK 环境下将 FreeRTOS 手动移植到 STM32G473VET6 微控制器上。内容涵盖工程创建、获取源码、文件组织、移植层适配、测试任务编写以及编译调试等步骤。 1. 工程搭建(Keil 项目创建) 创建基础工程:首先准备一个基…...
WPF中对滚动条进行平滑滚动
有时候我们在动态添加内容时,需要将滚动条滚动到指定内容处。 一般我们会调用ScrollViewer的ScrollToVerticalOffset(垂直方向)函数和ScrollToHorizontalOffset(水平方向)函数来控制滚动条滚动到指定位置。 正常滚动效…...
API,URL,Token,XML,JSON是干嘛的
API,URL,Token,XML,JSON是干嘛的 API的作用 API(Application Programming Interface,应用程序编程接口)是一组定义和协议,用于构建和交互软件应用程序。API允许不同的软件系统之间…...
Threejs 解析几何体提取顶点数据流程
目录 前言 原生WebGL 整体解析过程简介 顶点颜色属性Geometry.colors Geometry转化为BufferGeometry 相关函数 WebGLAttributes.js WebGLGeometries.js WebGLObjects.js WebGLRenderer.js WebGLRenderer.js 前言 解析几何体对象,提取顶点数据…...
浮动与清除浮动
浮动(float)是CSS中用于布局的重要属性,它使元素脱离正常的文档流,并向左或向右移动,直到碰到另一个浮动元素或父元素的边界。 浮动的定义和作用 定义:浮动是通过设置 float 属性使元素脱离正常的文档流&a…...
YOLOv5 + SE注意力机制:提升目标检测性能的实践
一、引言 目标检测是计算机视觉领域的一个重要任务,广泛应用于自动驾驶、安防监控、工业检测等领域。YOLOv5作为YOLO系列的最新版本,以其高效性和准确性在实际应用中表现出色。然而,随着应用场景的复杂化,传统的卷积神经网络在处…...
极简Redis速成学习
redis是什么? 是一种以键值对形式存储的数据库,特点是基于内存存储,读写快,性能高,常用于缓存、消息队列等应用情境 redis的五种数据类型是什么? 分别是String、Hash、List、Set和Zset(操作命…...
教育培训APP开发全攻略:从网校系统源码搭建到功能优化的技术方案
本篇文章,笔者将从网校系统源码搭建到功能优化的角度,全面解析教育培训APP的开发技术方案,帮助企业和开发者更好地理解如何提升在线教育平台的性能与用户体验。 一、教育培训APP开发的核心架构 教育培训APP的架构设计是其能否顺利运行和扩展…...
