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 類型。
  • 如果解析失敗或 directionnull,則使用默認值 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
}

小結

通過 BasePagetoPageable() 方法,我們實現了一個簡單而靈活的分頁模型。它的優點在于:

  • 簡單易用:只需設置幾個屬性,就能生成 Pageable 對象。
  • 默認值友好:未設置的參數有合理的默認值,避免空指針問題。
  • 支持排序:靈活指定排序字段和方向,滿足復雜需求。

當然,實際開發中還可以根據需求擴展 BasePage,比如添加參數驗證、支持多字段排序等。Spring Data JPA 的分頁功能非常強大,配合自定義模型類,可以讓代碼更優雅、更易維護。

如果你也正在為分頁功能苦惱,不妨試試這種方式吧!有什么問題或想法,歡迎在評論區交流。


在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70907.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70907.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70907.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android Studio 新版本Gradle發布本地Maven倉庫示例

發布代碼到JitPack示例&#xff1a;https://blog.csdn.net/loutengyuan/article/details/145938967 以下是基于 Android Studio 24.2.2&#xff08;Gradle 8.10.2 AGP 8.8.0 JDK17&#xff09; 的本地 Maven 倉庫發布示例&#xff0c;包含aar和jar的不同配置&#xff1a; 1.…

python量化交易——金融數據管理最佳實踐——qteasy創建本地數據源

文章目錄 qteasy金融歷史數據管理總體介紹本地數據源——DataSource對象默認數據源查看數據表查看數據源的整體信息最重要的數據表其他的數據表 從數據表中獲取數據向數據表中添加數據刪除數據表 —— 請盡量小心&#xff0c;刪除后無法恢復&#xff01;&#xff01;總結 qteas…

Android中使用Robolectric測試點擊事件(不需要手機)

文章目錄 一、前言二、簡單示例三、參考文檔 一、前言 Robolectric 是一個由 Google 維護的開源 Android 測試框架&#xff0c;它允許你以 Android 運行時環境運行單元測試。 Robolectric 提供了一個模擬 Android 運行時環境&#xff0c;允許你測試你的代碼是否正確地使用 And…

Spring Boot 接口 JSON 序列化優化:忽略 Null 值的九種解決方案詳解

一、針對特定接口null的處理&#xff1a; 方法一&#xff1a;使用 JsonInclude 注解 1.1 類級別&#xff1a;在接口返回的 ?DTO 類或字段? 上添加 JsonInclude 注解&#xff0c;強制忽略 null 值&#xff1a; 類級別&#xff1a;所有字段為 null 時不返回 JsonInclude(Js…

ds回答-開源llm應用開發平臺

以下是幾個著名的開源 LLM 應用開發平臺&#xff0c;涵蓋不同場景和技術特點&#xff1a; 1. Dify 特點&#xff1a;低代碼 / 無代碼開發、支持 RAG 檢索、Agent 智能體、模型管理、LLMOps 全流程優化。核心功能&#xff1a;可視化工作流編排、數百種模型兼容&#xff08;如 GP…

LDR6020 PD3.1 協議芯片在特定設備中的應用

在電子設備互聯互通的時代&#xff0c;芯片技術成為提升設備性能與功能的關鍵驅動力。LDR6020 PD3.1 協議芯片以其出色的性能&#xff0c;在 TYPE-C 臺式顯示器 / 便攜顯示器、一拖二快充線以及手機電腦轉接器等設備中展現出獨特價值&#xff0c;為用戶帶來更便捷、高效的使用體…

wzl-django學習

####################################################總的urls.py from django.contrib import admin from django.urls import path,include, re_path from django.views.static import serve from django.conf import settings from drf_yasg import openapi from drf_yas…

python -ssh學習

def exe_sshcmd(ip,username,userpswd,port,cmd): """ 功能&#xff1a;SSH登錄到指定設備&#xff0c;并執行對應的命令 入參&#xff1a;前四項為ssh登錄shell的ip和port&#xff0c;具備管理員權限的用戶名和密碼&#xff0c; cmd可以…

PDF處理控件Aspose.PDF教程:使用 Python 將 PDF 轉換為 TIFF

TIFF文件是高質量圖像的首選。它們廣泛用于印刷、存檔和圖形設計。企業通常需要轉換PDF文檔以獲得更好的兼容性。了解如何以編程方式執行此轉換可以節省時間和資源。在這篇教程中&#xff0c;我們將探討如何使用 Python 將 PDF 轉換為 TIFF。 本文涵蓋以下主題&#xff1a; P…

服務器IPMI用戶名、密碼批量檢查

背景 大規模服務器部署的時候&#xff0c;少不了較多的網管和監測平臺&#xff0c;這些平臺會去監控服務器的性能、硬件等指標參數&#xff0c;為了便于管理和控制&#xff0c;則需要給服務器IPMI帶外管理添加較多的用戶&#xff0c;這就需要對較多的服務器檢查所對應的IPMI用…

< 自用文兒 > Gobuster 暴力掃描工具與 SecLists 安全測試詞表集合

Ethice 道德問題 GFW 的保護下&#xff0c;很多的設備操作系統是停留在更老的版本&#xff0c;應用軟件也是&#xff0c;因此很多的漏洞沒有被修復。通訊沒有使用加密&#xff0c;例如網頁沒有使用 HTTPS 網站很多。幾乎是半裸的在網絡上等著被食。 不做惡是下限。 環境&…

【Cadence射頻仿真學習筆記】2.4GHz低噪放LNA仿真設計

課程分為3個部分&#xff0c; 一、LNA結構與噪聲優化方法 噪聲優化的方法是&#xff1a;限定功耗的噪聲和功率同時匹配噪聲匹配和功率匹配一般不會同時達到&#xff0c; 對于PCSNIM結構的噪聲分析&#xff0c;我們只需要了解與哪些參數有關優化思路是&#xff1a;1.信號源阻抗…

【洛谷入門賽】B4042 順序結構 202410 場

題意 給你一個變量 a a a&#xff1a;小 Y 會讓 a a a 先加 5 5 5 再把它們的和乘 3 3 3 最后輸出&#xff1b;小 L 會讓 a a a 先乘 3 3 3 再加 5 5 5 最后輸出。 要求出小 Y 和小 L 分別會輸出什么東西。 思路 這道題按照題目意思模擬就可以了&#xff0c;重點是考…

Android13修改多媒體默認音量

干就完了! 設置音量為最大音量,修改如下: /framework/base/media/java/android/media/AudioSystem.java/** hide */public static int[] DEFAULT_STREAM_VOLUME new int[] {4, // STREAM_VOICE_CALL7, // STREAM_SYSTEM5, // STREAM_RING-5, // STREAM_MUSIC15, // STREAM…

【Azure 架構師學習筆記】- Azure Databricks (13) -- 搭建Medallion Architecture part 1

本文屬于【Azure 架構師學習筆記】系列。 本文屬于【Azure Databricks】系列。 接上文 【Azure 架構師學習筆記】- Azure Databricks (12) – Medallion Architecture簡介 前言 上文已經介紹了關于Medallion的知識&#xff0c;本文開始用ADB 來實現&#xff0c; 但是基于內容較…

社交APP如何打造高粘性興趣社群

想要打造一款成功的社交 APP 興趣社群&#xff0c;關鍵在于充分激發用戶的主動分享意愿&#xff0c;同時構建起深度互動機制。與其在一開始就將大量資源投入到廣告宣傳中&#xff0c;倒不如把精力集中在深度挖掘和精心維護首批核心用戶上。例如&#xff0c;可以嘗試設計在線測試…

【操作系統】同步與互斥

同步與互斥 一、同步與互斥的概念1.1 同步與異步1.2 進程互斥 二、進程互斥的實現2.1 軟件實現2.1.1 單標志法2.1.2 雙標志先檢查法2.1.3 雙標志后檢查法2.1.4 Peterson法 2.2 硬件實現2.2.1 中斷指令2.2.2 TestAndSet指令2.2.3 Swap指令 三、互斥鎖四、信號量機制4.1 整型信號…

C++ 正則表達式分組捕獲入門指南

在 C 中&#xff0c;正則表達式&#xff08;regex&#xff09;是一種用于匹配字符串模式的強大工具。正則表達式不僅能幫助你查找符合特定模式的字符&#xff0c;還能捕獲匹配的子字符串&#xff08;即分組捕獲&#xff09;。這篇文章將介紹 C 正則表達式中的分組捕獲機制&…

使用Docker方式一鍵部署MySQL和Redis數據庫詳解

一、前言 數據庫是現代應用開發中不可或缺的一部分&#xff0c;MySQL和Redis作為兩種廣泛使用的數據庫系統&#xff0c;分別用于關系型數據庫和鍵值存儲。本文旨在通過Docker和Docker Compose的方式&#xff0c;提供一個簡潔明了的一鍵部署方案&#xff0c;確保數據庫服務的穩…

性能附錄:如何計算并發用戶數(摘自高樓老師《性能30講》)

高樓老師《性能30講》: 性能測試實戰30講-極客時間 感興趣的同學可以去讀一下&#xff0c;個人感覺寫的非常好 目錄 什么是并發? 在線用戶數、并發用戶數怎么計算 總結 什么是并發? 我們假設上圖中的這些小人是嚴格按照這個邏輯到達系統的&#xff0c;那顯然&#xff0c;…