当前位置: 首页 > article >正文

Spring Boot分页查询进阶:整合Spring Data REST实现高效数据导航

目录:

  1. 引言
  2. 分页查询基础回顾
    2.1 Spring Data JPA分页接口
    2.2 Pageable与Page的使用
    2.3 常见分页参数设计
  3. Spring Data REST简介
    3.1 HATEOAS与超媒体驱动API
    3.2 Spring Data REST核心功能
    3.3 自动暴露Repository接口
  4. 整合Spring Boot与Spring Data REST
    4.1 项目依赖与配置
    4.2 自定义Repository REST资源
    4.3 分页查询自动链接示例
  5. 高级定制:动态筛选与分页导航
    5.1 Querydsl结合Spring Data REST
    5.2 参数解析与Specification实现
    5.3 自定义分页元数据扩展
  6. 实战案例:商品管理微服务
    6.1 领域模型与数据库设计
    6.2 常见分页场景实现
    6.3 前端集成示例(Vue.js/Angular)
  7. 性能优化策略
    7.1 避免N+1查询与批量抓取
    7.2 索引与分区策略
    7.3 缓存分页结果与Redis
  8. 安全与限流
    8.1 JWT身份认证与权限控制
    8.2 分页接口防刷策略
  9. 常见问题与排查
    9.1 总页数计算不准确
    9.2 路由403/404问题
    9.3 性能瓶颈定位

  1. 引言

在现代微服务架构中,客户端经常需要分页加载海量数据,如电商商品、日志记录或社交动态。传统API往往返回固定格式的分页结果,开发者需手动拼装分页链接,既繁琐又易出错。Spring Data REST基于HATEOAS超媒体原则,可自动生成上一页、下一页、首尾页链接,实现零侵入式的数据导航效果。本文将带领读者一步步掌握Spring Boot分页查询进阶技巧,助力打造高效、友好的RESTful分页接口。

  1. 分页查询基础回顾

2.1 Spring Data JPA分页接口
Spring Data JPA提供了PagingAndSortingRepository,继承自CrudRepository,额外暴露了分页和排序接口。常用方法:

public interface UserRepository extends PagingAndSortingRepository<User, Long> {// 继承分页与排序能力,无需额外定义
}

开发者可直接通过repository.findAll(Pageable pageable)获取Page<T>对象,其中包含总记录数、总页数及当前页内容。

2.2 Pageable与Page的使用
org.springframework.data.domain.Pageable用于封装分页请求参数,常见构造方式:

Pageable pageable = PageRequest.of(pageIndex, pageSize, Sort.by("createdAt").descending());
Page<User> page = userRepository.findAll(pageable);

Page<T>则包含:

  • getContent():当前页列表
  • getTotalPages():总页数
  • hasNext() / hasPrevious():是否可翻页
  • getPageable():当前分页参数

2.3 常见分页参数设计
为了方便前端交互,我们一般在URL中使用?page=0&size=20&sort=createdAt,desc参数格式,Spring Boot通过PageableHandlerMethodArgumentResolver自动解析。可在配置中全局定制默认页大小与最大页大小:

spring:data:web:pageable:default-page-size: 20max-page-size: 100
  1. Spring Data REST简介

3.1 HATEOAS与超媒体驱动API
HATEOAS(Hypermedia as the Engine of Application State)是一种REST设计原则,强调服务端在响应中提供必要的链接,指导客户端下一步操作。Spring HATEOAS提供EntityModel<T>Link构建超媒体资源。

3.2 Spring Data REST核心功能
Spring Data REST通过扫描项目中继承Repository的接口,自动生成对应的CRUD REST API,并支持分页、排序、投影、事件拦截器等多项功能,极大降低开发成本。

3.3 自动暴露Repository接口
只需添加依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

Spring Boot启动后,访问/users即可得到分页响应:

{"_embedded": {"users": [...]},"page": {"size":20,"totalElements":100,"totalPages":5,"number":0},"_links": {"self":...,"next":...,"prev":...,"first":...,"last":...}
}
  1. 整合Spring Boot与Spring Data REST

4.1 项目依赖与配置
pom.xml中同时引入:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

application.yml中开启HATEOAS链接暴露:

spring:data:rest:default-page-size: 20max-page-size: 100base-path: /api

4.2 自定义Repository REST资源
若想自定义暴露路径或方法名称,可在接口上添加@RepositoryRestResource注解:

@RepositoryRestResource(path = "accounts", collectionResourceRel = "accounts")
public interface AccountRepository extends PagingAndSortingRepository<Account, Long> {Page<Account> findByStatus(@Param("status") String status, Pageable pageable);
}

访问/api/accounts/search/findByStatus?status=ACTIVE即可分页查询。

4.3 分页查询自动链接示例
示例响应:

{"_embedded": {"accounts":[...]},"page":{"size":20,"totalElements":45,"totalPages":3,"number":1},"_links":{"self":{"href":"http://.../accounts?page=1&size=20"},"first":{"href":"...page=0"},"prev":{"href":"...page=0"},"next":{"href":"...page=2"},"last":{"href":"...page=2"}}
}
  1. 高级定制:动态筛选与分页导航

5.1 Querydsl结合Spring Data REST
集成Querydsl后,可动态构建复杂查询:

public interface ProductRepository extends QuerydslPredicateExecutor<Product>, PagingAndSortingRepository<Product, Long> {}

前端传入?predicate=name.contains=book;price.gt=100&page=0&size=10即可组合查询和分页。

5.2 参数解析与Specification实现
使用JpaSpecificationExecutor

public interface OrderRepository extends JpaSpecificationExecutor<Order>, PagingAndSortingRepository<Order, Long> {}
// 构造Specification
Specification<Order> spec = (root, query, cb) -> cb.equal(root.get("status"), status);
Page<Order> result = orderRepository.findAll(spec, pageable);

通过自定义PageableHandlerMethodArgumentResolverCustomizer可让REST端点解析spec参数。

5.3 自定义分页元数据扩展
可实现RepresentationModelProcessor<CollectionModel<?>>,为分页响应添加自定义元数据:

@Component
public class PageMetadataProcessor implements RepresentationModelProcessor<CollectionModel<?>> {@Overridepublic CollectionModel<?> process(CollectionModel<?> model) {model.add(Link.of("/api/docs/pagination", "pagination-docs"));return model;}
}
  1. 实战案例:商品管理微服务

6.1 领域模型与数据库设计

  • Product实体:id, name, description, price, category, createdAt
  • 索引:price、category字段建立索引

6.2 常见分页场景实现

  • 全量分页
  • 分类筛选分页:/products/search/findByCategory?category=electronics
  • 价格区间分页组合查询

6.3 前端集成示例(Vue.js)

async fetchProducts(page = 0) {const res = await axios.get(`/api/products?page=${page}&size=20`);this.products = res.data._embedded.products;this.links = res.data._links;
}

通过links.next.href动态生成下一页按钮。

  1. 性能优化策略

7.1 避免N+1查询与批量抓取
使用@EntityGraphjoin fetch解决懒加载触发的N+1问题。

7.2 索引与分区策略
针对大表,可考虑范围分区或HASH分区,并对分页字段进行复合索引。

7.3 缓存分页结果与Redis
基于Spring Cache将分页结果按页存入Redis,减少数据库压力。

  1. 安全与限流

8.1 JWT身份认证与权限控制
通过@PreAuthorize("hasRole('ROLE_USER')")控制不同分页接口访问权限。

8.2 分页接口防刷策略
基于令牌桶算法对分页请求进行限流,并结合用户身份鉴别。

  1. 常见问题与排查

9.1 总页数计算不准确
检查totalElements返回值是否受到过滤器或Specification影响。

9.2 路由403/404问题
确认Repository路径与base-path配置一致,并检查CORS策略。

9.3 性能瓶颈定位
使用Spring Boot Actuator和Micrometer进行请求跟踪与时序数据库监控。

相关文章:

Spring Boot分页查询进阶:整合Spring Data REST实现高效数据导航

目录&#xff1a; 引言分页查询基础回顾 2.1 Spring Data JPA分页接口 2.2 Pageable与Page的使用 2.3 常见分页参数设计Spring Data REST简介 3.1 HATEOAS与超媒体驱动API 3.2 Spring Data REST核心功能 3.3 自动暴露Repository接口整合Spring Boot与Spring Data REST 4.1 项目…...

阿里云 Serverless 助力海牙湾构建弹性、高效、智能的 AI 数字化平台

作者&#xff1a;赵世振、十眠、修省 “通过阿里云 Serverless 架构&#xff0c;我们成功解决了弹性能力不足、资源浪费与运维低效的痛点。SAE 的全托管特性大幅降低技术复杂度。未来&#xff0c;我们将进一步探索 Serverless 与 AI 的结合&#xff0c;为客户提供更智能的数字…...

升级node@22后运行npm install报错 distutils not found

从node20升级到node22后&#xff0c;在运行 npm install 的时候报了很多 gyp 错误&#xff0c;其中包括 npm error npm error ModuleNotFoundError: No module named distutils。 问题原因是我在使用 brew install node22 的过程中自动把 python 升级到了 3.13。而 distutils …...

一个开源的多播放源自动采集在线影视网站

这里写自定义目录标题 欢迎使用Markdown编辑器GoFilm简介项目部署1、前置环境准备1.2 redis 配置 film-api 后端服务配置将 GoFilm 项目根目录下的 film 文件夹上传到 linux 服务器的 /opt 目录下 2. 构建运行1. docker 部署1.1 安装 docker , docker compose 环境 注意事项: 2…...

【PhysUnits】10 减一操作(sub1.rs)

一、源码 代码实现了一个类型级别的减一操作(Sub1 trait)&#xff0c;通过Rust的类型系统在编译期完成数值减一的计算。 //! 减一操作特质实现 / Decrement operation trait implementation //! //! 提供类型级别的减一计算 / Provides type-level decrement operationuse su…...

深度检测与动态透明度控制 - 基于Babylon.js的遮挡检测实现解析

首先贴出实现代码&#xff1a; OcclusionFader.ts import { AbstractEngine, Material, type Behavior, type Mesh, type PBRMetallicRoughnessMaterial, type Scene } from "babylonjs/core"; import { OcclusionTester } from "../../OcclusionTester"…...

Linux下使用socat将TCP服务转为虚拟串口设备

Linux下使用socat将TCP服务转为虚拟串口设备 socat是一个强大的网络工具&#xff0c;可以将TCP连接转换为虚拟串口设备&#xff0c;这在嵌入式开发、工业控制等领域非常有用。下面详细介绍如何实现这一功能。 基本原理 socat可以通过创建伪终端(PTY)来模拟串口设备&#xff…...

docker push 报错 denied: requested access to the resource is denied

问题&#xff1a;当 docker logout -> docker login 用户登录&#xff0c;但仍然无法 docker push $ docker push <username>/nginx-custom:v1 The push refers to repository [docker.io/jagger/nginx-custom] 340e6d3ea0c7: Preparing 941dd9dd8ee4: Preparing f6…...

epub→pdf | which 在线转换??好用!!

1、PDF派&#xff08;free&quick) pdf转word_pdf转换成excel_pdf转换成ppt _纬来PDF转换器 评价&#xff1a;目前使用免费&#xff0c;转化的时候有进度条提示&#xff0c;总的来说比较快&#xff0c;50mb的文件在40秒内可以转换完成&#xff0c;推荐 2、pdfconvert(free…...

PBX、IP PBX、FXO 、FXS 、VOIP、SIP 的概念解析以及关系

PBX&#xff08;Private Branch Exchange&#xff09; 概念 &#xff1a;PBX 是专用交换机&#xff0c;是一种在企业或组织内部使用的电话交换系统。它允许内部用户之间以及内部用户与外部公共电话网络&#xff08;PSTN&#xff09;之间进行通信。例如&#xff0c;在一个大型企…...

MySQL数据高效集成到金蝶云星空的技术分享

MySQL数据集成到金蝶云星空的技术案例分享&#xff1a;SR新建调拨单内部供应商-深圳天一 在企业信息化系统中&#xff0c;数据的高效流动和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例——将MySQL中的数据集成到金蝶云星空&#xff0c;以支持…...

git 命令之-git cherry-pick

今天得到一个通知&#xff0c;这个业务版本里面部分已经开发但还没测试的内容要新开一个分支提交&#xff0c;但是我已经有几个提交上去了&#xff0c;难道只能一个一个文件复制到新的分支吗&#xff1f;我不&#xff0c;我找到了这个git命令&#xff0c;可以解决我的困惑&…...

如何在STM32CubeMX下为STM32工程配置调试打印功能

为STM32工程配置调试打印功能 一、配置调试用的打印串口 #include <stdio.h> //标准输入输出库//1.在STM32CubeMX中打开并配置好某串口设备&#xff1b; //2.在main.c文件中添加如下代码行对输入输出重定向&#xff1b; //3.在文件开头包含stdio.h头文件。 #pragma im…...

Linux系统 - 基本概念

介绍一些Linux系统的基本概念 1 操作系统的核心—内核 “操作系统”通常包含两种不同含义。 1&#xff0e;指完整的软件包&#xff0c;这包括用来管理计算机资源的核心层软件&#xff0c;以及附带的所有标准软件工具&#xff0c;诸如命令行解释器、图形用户界面、文件操作工具…...

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器 js 代码 其他地方用直接导入js getCurrentUserId 这是自己后端获取 域账号地址 我是成功返回200 //true普通浏览器 fasle 无痕浏览器 export const checkBrowserMode async () > {try {const response a…...

在h5端实现录音发送功能(兼容内嵌微信小程序) recorder-core

本文将通过一个实际的 Vue3 组件示例&#xff0c;带你一步步实现“按住录音&#xff0c;松开发送&#xff0c;上滑取消”的语音录制功能。 我们将使用强大且小巧的开源库 recorder-core&#xff0c;支持 MP3、WAV、AAC 等编码格式&#xff0c;兼容性较好。 &#x1f527; 项目…...

PDF电子发票数据提取至Excel

声明&#xff1a;本软件是吾爱大佬th4c3y原创&#xff0c;本人只是搬运工&#xff01; 发票识别更新记录 【2025-3-14】更新 v2.0 在字段设置中新增自定义字段&#xff08;仅在 PDF 正则式接口下生效&#xff09;&#xff0c;支持自定义正则表达式或固定字符。 自定义字段会…...

【身份证识别表格】把大量手机拍摄的身份证信息转换成EXCEL表格的数据,拍的身份证照片转成excel表格保存,基于WPF和腾讯OCR的实现方案

基于WPF和腾讯OCR的身份证照片转Excel方案 应用场景 ​​企业人事管理​​&#xff1a;新员工入职时批量录入数百份身份证信息&#xff0c;传统手动录入易出错且耗时。通过OCR自动提取姓名、身份证号等字段&#xff0c;生成结构化Excel表格&#xff0c;效率提升10倍以上。 ​​…...

FPGA高速接口 mipi lvds cameralink hdml 千兆网 sdi

mipi: https://blog.csdn.net/SDJ_success/article/details/146541776 cameralink CameraLink协议 CameraLink协议是一种专门针对机器视觉应用领域的串行通信协议&#xff0c;它使用低压差分信号(LVDS)进行数据的传输和通信。CameraLink标准是在ChannelLink标准的基础上多加了…...

Linux路径解析指南:逻辑路径 vs 实际路径详解

在 Linux 系统中&#xff0c;逻辑路径&#xff08;Logical Path&#xff09;和 实际路径&#xff08;Physical Path&#xff09;是两个不同的概念&#xff0c;主要区别在于它们如何解析文件或目录的位置。以下是详细解释&#xff1a; 目录 1. 逻辑路径&#xff08;Logical Path…...

Azure 公有云基础架构与核心服务:从基础到实践指南

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 Azure 的基础架构由多个核心组件构成&#xff0c;理解这些概念是掌握其技术框架的第一步&#xff1a; 地理区域&#xff08;Geographic R…...

【运维_日常报错解决方案_docker系列】一、docker系统不起来

今天忽然想起来哎&#xff0c;还有一台”尘封“着的服务器&#xff0c;好久没用了&#xff0c;就随便打开登了登&#xff0c;然后想看一下服务器上面还有正在跑着的容器服务吗&#xff0c;然后使用docker ps 发现报错了。 然后重启也是下面这个状态。 查看docker状态&#xf…...

C# 数组与字符串:全面解析与应用实践

在C#编程语言中&#xff0c;数组和字符串是两种最基础也是最重要的数据类型。无论是简单的控制台应用程序&#xff0c;还是复杂的企业级系统&#xff0c;数组和字符串都扮演着不可或缺的角色。本文将全面深入地探讨C#中数组和字符串的特性、使用方法、性能考量以及实际应用场景…...

前端vue中使用signalr

一、引入SignalR库 使用NPM引入SignalR库 npm install @microsoft/signalrJs文件中引入 import * as signalR from @microsoft/signalr;二、初始化连接 这一步需要指定SignalR Hub的URL。 const connection = new signalR.HubConnectionBuilder().withUrl("https://y…...

Stable Diffusion底模对应的VAE推荐

以下是主流Stable Diffusion底模对应的VAE推荐表格&#xff1a; 底模版本推荐VAE类型说明SD1.5SD1.5专用VAE通常使用vae-ft-mse-840000-ema-pruned.safetensorsSD2.0SD1.5兼容VAE或SD2专用VAE部分SD2模型需配套512-ema-only.vae.ptSD3内置VAESD3系列模型通常自带集成VAE无需额…...

centos7.5安装kubernetes1.25.0

centos7.5安装kubernetes centos7.5kubernetes1&#xff09;准备阶段准备2台虚拟机配置静态IP修改主机名桥接设置配置阿里云的repo源配置k8s切国际源配置时间同步安装基础软件包 2)安装containerd服务安装配置开启启动 3)安装k8s4)安装kubersphere下载helm安装包解压将helm配置…...

‌AT2659S射频前端芯片技术解析:L1频段低噪声高增益GNSS信号放大

以下是关于‌AT2659S L1频段卫星导航射频前端芯片‌的客观描述&#xff0c;严格基于用户提供的原始信息&#xff0c;采用分享式表述&#xff0c;保持参数和核心内容不变&#xff1a; AT2659S芯片概述‌ AT2659S是一款基于SiGe工艺的射频前端芯片&#xff0c;专为L1频段&#…...

ROS2学习(15)------ROS2 TF2 机器人坐标系管理器

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 ROS版本&#xff1a;2 在 ROS 2 中&#xff0c;TF2&#xff08;Transform Library, v2&#xff09; 是一个非常核心的工具库&#xff0c;用于管理多个坐标系之间的 变换关系&#xff08;tran…...

每日c/c++题 备战蓝桥杯(洛谷P3382 三分法求极值详解)

洛谷P3382 三分法求极值详解 题目描述 P3382 三分法 要求在给定区间内寻找一个多项式函数的最大值点。题目保证函数在区间内先严格递增后严格递减&#xff08;单峰函数&#xff09;&#xff0c;适合使用三分法求解。 算法原理 三分法核心思想 对于单峰函数&#xff0c;在区…...

Vue+css实现扫描动画效果(使用@keyframes scan)

实现效果 扫描效果 参考链接 MDN Web Docs: CSS Animations 关键代码 示例代码 <div class"scanner-container"><div class"scanner-line"></div><div class"scanner-icon">&#x1f4f7;</div><p>Scan m…...