最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis分頁查詢實(shí)戰(zhàn)案例完整流程

 更新時(shí)間:2025年09月10日 11:10:09   作者:西域情歌  
MyBatis是一個(gè)強(qiáng)大的Java持久層框架,支持自定義SQL和高級映射,本案例以員工工資信息管理為例,詳細(xì)講解如何在IDEA中使用MyBatis結(jié)合PageHelper插件實(shí)現(xiàn)分頁查詢功能,感興趣的朋友跟隨小編一起看看吧

簡介:MyBatis是一個(gè)強(qiáng)大的Java持久層框架,支持自定義SQL和高級映射。在處理大數(shù)據(jù)量場景時(shí),分頁查詢是提升系統(tǒng)性能的重要手段。本案例以員工工資信息管理為例,詳細(xì)講解如何在IDEA中使用MyBatis結(jié)合PageHelper插件實(shí)現(xiàn)分頁查詢功能。內(nèi)容涵蓋PageHelper的引入方式、Mapper接口的定義、服務(wù)層與控制層的調(diào)用流程,以及前后端交互的分頁數(shù)據(jù)結(jié)構(gòu)。通過該實(shí)戰(zhàn)案例,開發(fā)者可以快速掌握MyBatis分頁查詢的完整實(shí)現(xiàn)流程,提升開發(fā)效率與系統(tǒng)性能。

1. MyBatis框架簡介

MyBatis 是一個(gè)輕量級但功能強(qiáng)大的持久層框架,它摒棄了傳統(tǒng)的全自動(dòng)ORM映射方式,轉(zhuǎn)而提供靈活的 SQL 控制能力。通過 XML 配置文件或注解方式,開發(fā)者可以精準(zhǔn)定義 SQL 語句,并實(shí)現(xiàn) Java 對象與數(shù)據(jù)庫記錄之間的映射。其核心組件包括 SqlSessionFactory SqlSession 、 Mapper 接口及 XML 映射文件,構(gòu)成了一個(gè)松耦合、易擴(kuò)展的數(shù)據(jù)訪問層架構(gòu)。在企業(yè)級開發(fā)中,MyBatis 憑借其高性能、易調(diào)試和靈活的 SQL 管理機(jī)制,被廣泛應(yīng)用于復(fù)雜業(yè)務(wù)場景下的數(shù)據(jù)持久化處理,為實(shí)現(xiàn)如分頁查詢等功能提供了堅(jiān)實(shí)的基礎(chǔ)。

2. 分頁查詢原理與應(yīng)用場景

2.1 分頁查詢的基本原理

2.1.1 分頁查詢的定義

分頁查詢(Pagination Query)是指在處理大量數(shù)據(jù)時(shí),將數(shù)據(jù)按照一定數(shù)量劃分為多個(gè)“頁”進(jìn)行查詢和展示的技術(shù)。在Web應(yīng)用中,這種機(jī)制被廣泛使用,尤其是在處理成千上萬條數(shù)據(jù)時(shí),避免一次性加載全部數(shù)據(jù)到前端,從而提升用戶體驗(yàn)和系統(tǒng)性能。

分頁的核心思想是: 每次只加載用戶當(dāng)前需要查看的數(shù)據(jù),而不是全部數(shù)據(jù) 。通過這種方式,可以有效降低服務(wù)器壓力,提升響應(yīng)速度,并優(yōu)化數(shù)據(jù)庫查詢效率。

2.1.2 分頁機(jī)制的工作流程

分頁機(jī)制的典型工作流程如下:

  1. 前端請求 :用戶在頁面上點(diǎn)擊下一頁、上一頁或跳轉(zhuǎn)頁碼。
  2. 參數(shù)傳遞 :前端將當(dāng)前頁碼(pageNum)和每頁顯示數(shù)量(pageSize)作為參數(shù)傳遞給后端接口。
  3. 后端處理
    - 解析請求參數(shù) pageNum 和 pageSize;
    - 構(gòu)建帶分頁條件的 SQL 查詢語句;
    - 執(zhí)行查詢,獲取當(dāng)前頁數(shù)據(jù);
    - 同時(shí)獲取總記錄數(shù)用于計(jì)算總頁數(shù);
  4. 結(jié)果返回 :將當(dāng)前頁數(shù)據(jù)和分頁信息(如總記錄數(shù)、總頁數(shù))封裝后返回給前端;
  5. 前端展示 :前端根據(jù)返回?cái)?shù)據(jù)展示當(dāng)前頁數(shù)據(jù),并渲染分頁控件。

2.1.3 數(shù)據(jù)庫層面的分頁實(shí)現(xiàn)方式

不同的數(shù)據(jù)庫系統(tǒng)支持的分頁語法略有不同。以下是主流數(shù)據(jù)庫的分頁實(shí)現(xiàn)方式:

數(shù)據(jù)庫類型分頁語法示例說明
MySQLSELECT * FROM users LIMIT 10 OFFSET 20 LIMIT 指定每頁條數(shù), OFFSET 指定偏移量
PostgreSQLSELECT * FROM users LIMIT 10 OFFSET 20 與MySQL語法一致
OracleSELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM users) A WHERE ROWNUM <= 20) WHERE RN > 10 使用嵌套子查詢和ROWNUM實(shí)現(xiàn)分頁
SQL ServerSELECT * FROM users ORDER BY id OFFSET 10 ROWS FETCH NEXT 20 ROWS ONLY 使用OFFSET和FETCH實(shí)現(xiàn)分頁

以MySQL為例的分頁SQL解析:

SELECT * FROM users LIMIT 10 OFFSET 20;
  • LIMIT 10 :每頁顯示10條數(shù)據(jù);
  • OFFSET 20 :從第21條數(shù)據(jù)開始(即跳過前20條);

該SQL語句將返回第3頁的數(shù)據(jù)(假設(shè)每頁10條),即第21~30條記錄。

2.2 分頁查詢的典型應(yīng)用場景

2.2.1 Web應(yīng)用中的數(shù)據(jù)列表展示

在Web應(yīng)用中,數(shù)據(jù)列表是常見的展示形式,例如用戶管理、訂單列表、商品信息等。由于數(shù)據(jù)量可能非常龐大,一次性加載所有數(shù)據(jù)不僅影響用戶體驗(yàn),還會(huì)造成資源浪費(fèi)。

分頁在數(shù)據(jù)列表中的作用:

  • 減少頁面加載時(shí)間;
  • 提高頁面響應(yīng)速度;
  • 提升用戶體驗(yàn),避免信息過載;
  • 便于數(shù)據(jù)的瀏覽與導(dǎo)航。

示例:

一個(gè)電商系統(tǒng)中,商品總數(shù)為10萬條。若一次性加載所有商品信息,頁面加載時(shí)間將極長,甚至導(dǎo)致瀏覽器卡頓。使用分頁機(jī)制后,可以每次只加載100條數(shù)據(jù),用戶點(diǎn)擊翻頁時(shí)再加載后續(xù)數(shù)據(jù)。

2.2.2 大數(shù)據(jù)量下的性能優(yōu)化需求

在處理大數(shù)據(jù)量時(shí),數(shù)據(jù)庫查詢的性能尤為重要。如果不對查詢進(jìn)行分頁限制,可能會(huì)導(dǎo)致以下問題:

  • 查詢響應(yīng)時(shí)間長 :全表掃描會(huì)消耗大量資源;
  • 內(nèi)存占用高 :一次性加載大量數(shù)據(jù)可能超出內(nèi)存限制;
  • 數(shù)據(jù)庫連接阻塞 :長時(shí)間的查詢會(huì)占用數(shù)據(jù)庫連接,影響其他操作。

解決方案:

使用分頁查詢可以有效限制返回?cái)?shù)據(jù)量,從而:

  • 減少數(shù)據(jù)庫掃描的數(shù)據(jù)量;
  • 降低I/O和CPU使用率;
  • 縮短查詢響應(yīng)時(shí)間;
  • 提高并發(fā)處理能力。

性能優(yōu)化技巧:

  • 使用索引字段作為排序條件;
  • 避免使用 SELECT * ,只查詢需要的字段;
  • 對查詢條件進(jìn)行合理索引;
  • 分頁深度優(yōu)化(如游標(biāo)分頁)。

2.2.3 分頁在前后端交互中的作用

分頁查詢不僅是一種數(shù)據(jù)庫層面的技術(shù),它在前后端交互中也扮演著重要角色。

前端視角:

  • 分頁控件(如“上一頁”、“下一頁”、“跳轉(zhuǎn)頁碼”)提供良好的用戶交互體驗(yàn);
  • 支持動(dòng)態(tài)加載數(shù)據(jù),實(shí)現(xiàn)懶加載或無限滾動(dòng);
  • 提供分頁狀態(tài)管理(如當(dāng)前頁、總頁數(shù)、總記錄數(shù));

后端視角:

  • 分頁接口設(shè)計(jì)規(guī)范統(tǒng)一;
  • 接口返回結(jié)構(gòu)標(biāo)準(zhǔn)化(如包含數(shù)據(jù)列表、總記錄數(shù)、當(dāng)前頁碼等);
  • 分頁信息封裝為對象(如PageInfo)以便前端處理;

前后端交互流程示意圖(mermaid):

sequenceDiagram
    用戶->>前端: 點(diǎn)擊下一頁
    前端->>后端: 發(fā)送pageNum=2, pageSize=10
    后端->>數(shù)據(jù)庫: 執(zhí)行分頁SQL查詢
    數(shù)據(jù)庫-->>后端: 返回第2頁數(shù)據(jù)
    后端-->>前端: 返回JSON格式分頁結(jié)果
    前端-->>用戶: 展示第2頁數(shù)據(jù)

2.3 MyBatis中實(shí)現(xiàn)分頁的方式概述

2.3.1 手動(dòng)拼接SQL分頁

手動(dòng)拼接SQL是最原始的分頁實(shí)現(xiàn)方式,開發(fā)者需要在SQL語句中根據(jù)頁碼和每頁大小動(dòng)態(tài)計(jì)算偏移量并拼接LIMIT/OFFSET。

示例代碼(MyBatis XML):

<select id="selectUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null">
            AND name LIKE CONCAT('%', #{name}, '%')
        </if>
    </where>
    LIMIT #{pageSize} OFFSET #{offset}
</select>

Java調(diào)用示例:

int pageNum = 2;
int pageSize = 10;
int offset = (pageNum - 1) * pageSize;
List<User> users = userMapper.selectUsers(offset, pageSize);

優(yōu)點(diǎn):

  • 靈活,適用于各種數(shù)據(jù)庫;
  • 無需依賴第三方插件;

缺點(diǎn):

  • 需要手動(dòng)計(jì)算偏移量;
  • 不利于代碼復(fù)用;
  • 分頁邏輯分散在業(yè)務(wù)代碼中;

2.3.2 使用PageHelper插件自動(dòng)分頁

PageHelper是MyBatis官方推薦的分頁插件,它可以自動(dòng)攔截SQL并添加分頁語句,大大簡化了分頁邏輯的實(shí)現(xiàn)。

使用示例:

PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
PageInfo<User> pageInfo = new PageInfo<>(users);

對應(yīng)的SQL執(zhí)行過程:

SELECT * FROM users LIMIT 10 OFFSET 10;
SELECT COUNT(*) FROM users;

優(yōu)點(diǎn):

  • 簡潔高效,一行代碼實(shí)現(xiàn)分頁;
  • 自動(dòng)處理COUNT查詢;
  • 支持多種數(shù)據(jù)庫;
  • 與MyBatis無縫集成;

缺點(diǎn):

  • 依賴PageHelper插件;
  • 對某些復(fù)雜查詢支持有限;

2.3.3 分頁插件與原生SQL的對比分析

特性原生SQL手動(dòng)分頁PageHelper插件分頁
實(shí)現(xiàn)方式手動(dòng)拼接LIMIT/OFFSET自動(dòng)攔截并修改SQL
分頁邏輯分散在業(yè)務(wù)代碼中集中統(tǒng)一處理
維護(hù)成本高,容易出錯(cuò)低,易于維護(hù)
支持COUNT查詢需手動(dòng)編寫自動(dòng)添加
靈活性高,可自定義依賴插件配置
性能影響無額外開銷插件有一定性能開銷
推薦場景簡單查詢、數(shù)據(jù)庫兼容要求高中大型項(xiàng)目、快速開發(fā)

結(jié)論:

  • 對于小型項(xiàng)目或特定數(shù)據(jù)庫兼容需求,可以使用原生SQL手動(dòng)分頁;
  • 對于中大型項(xiàng)目、快速開發(fā)和標(biāo)準(zhǔn)化分頁處理,推薦使用PageHelper插件;
  • 在使用PageHelper時(shí),需注意其對復(fù)雜查詢(如JOIN、子查詢)的兼容性,并結(jié)合實(shí)際情況選擇使用方式。

3. PageHelper插件集成與配置

在實(shí)際開發(fā)中,處理大量數(shù)據(jù)時(shí)分頁查詢是必不可少的。PageHelper 是 MyBatis 中非常流行的一款分頁插件,它能夠簡化分頁邏輯,避免手動(dòng)拼接 SQL 分頁語句的復(fù)雜性。本章將深入講解如何將 PageHelper 插件集成到項(xiàng)目中,并進(jìn)行相關(guān)配置與使用,為后續(xù)章節(jié)中分頁方法的實(shí)現(xiàn)打下堅(jiān)實(shí)基礎(chǔ)。

3.1 PageHelper插件概述

PageHelper 是一個(gè)專為 MyBatis 設(shè)計(jì)的分頁插件,能夠自動(dòng)識別 SQL 語句并進(jìn)行分頁處理,極大提升了開發(fā)效率和代碼可維護(hù)性。

3.1.1 PageHelper的功能與優(yōu)勢

PageHelper 提供了以下核心功能:

  • 自動(dòng)分頁 :通過簡單的 API 調(diào)用即可實(shí)現(xiàn) SQL 分頁。
  • 多數(shù)據(jù)庫支持 :支持 MySQL、Oracle、SQL Server、PostgreSQL 等主流數(shù)據(jù)庫。
  • 靈活配置 :允許配置分頁參數(shù)、合理化分頁、默認(rèn)頁面大小等。
  • 兼容性好 :與 Spring、Spring Boot、MyBatis 注解和 XML 映射方式兼容良好。
  • 性能優(yōu)化 :底層采用攔截器機(jī)制,對 SQL 進(jìn)行改寫,減少冗余操作。

相較于手動(dòng)拼接 SQL 分頁,使用 PageHelper 的優(yōu)勢在于:

  • 開發(fā)效率高 :減少重復(fù)代碼。
  • 可維護(hù)性強(qiáng) :集中管理分頁邏輯。
  • 擴(kuò)展性好 :支持多種數(shù)據(jù)庫和自定義分頁策略。

3.1.2 插件的版本選擇與兼容性分析

PageHelper 的版本更新頻繁,不同版本與 MyBatis 和 Spring Boot 的兼容性略有不同。常見版本如下:

PageHelper 版本MyBatis 版本要求Spring Boot 版本建議說明
5.2.0≥3.4.0≥2.0.0最新穩(wěn)定版,推薦使用
5.1.11≥3.4.0≥1.5.0穩(wěn)定版本,廣泛使用
4.x3.x1.x舊版,不推薦新項(xiàng)目使用

在選擇版本時(shí),應(yīng)優(yōu)先考慮與當(dāng)前項(xiàng)目依賴版本的匹配性。推薦使用 5.2.0 5.1.11 版本。

3.2 PageHelper的引入與配置

為了在項(xiàng)目中使用 PageHelper,需要將其作為依賴引入,并在 MyBatis 或 Spring Boot 配置文件中進(jìn)行相應(yīng)設(shè)置。

3.2.1 Maven依賴的引入方式

pom.xml 中添加如下依賴:

<!-- MyBatis PageHelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>5.2.0</version>
</dependency>

說明:

  • pagehelper-spring-boot-starter 是 Spring Boot 項(xiàng)目專用的 starter 模塊,自動(dòng)完成插件的配置。
  • 若非 Spring Boot 項(xiàng)目,可使用 pagehelper 模塊,并手動(dòng)配置插件。

3.2.2 在MyBatis配置文件中添加插件配置

對于非 Spring Boot 項(xiàng)目(傳統(tǒng) Spring + MyBatis),需在 mybatis-config.xml 中手動(dòng)添加插件配置:

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 可選參數(shù) -->
        <property name="helperDialect" value="mysql"/>
        <property name="reasonable" value="true"/>
        <property name="supportMethodsArguments" value="true"/>
        <property name="params" value="count=countSql"/>
    </plugin>
</plugins>

參數(shù)說明:

參數(shù)名含義示例值
helperDialect指定數(shù)據(jù)庫方言mysql、oracle、sqlserver
reasonable是否啟用合理化分頁(頁碼超出范圍時(shí)自動(dòng)調(diào)整)true、false
supportMethodsArguments是否支持通過 Mapper 接口參數(shù)傳遞分頁信息true
params配置 count 查詢的參數(shù)名count=countSql

3.2.3 Spring Boot項(xiàng)目中的自動(dòng)配置方式

在 Spring Boot 項(xiàng)目中,除了引入依賴,還可以通過 application.yml application.properties 文件進(jìn)行配置:

pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true
  params: count=countSql

說明:

  • helper-dialect :指定數(shù)據(jù)庫類型,用于分頁 SQL 的自動(dòng)改寫。
  • reasonable :開啟合理化分頁,如當(dāng)前頁碼大于最大頁碼時(shí),自動(dòng)返回最后一頁數(shù)據(jù)。
  • support-methods-arguments :啟用接口方法參數(shù)中分頁信息的自動(dòng)識別。
  • params :定義 count 查詢參數(shù)名稱。

3.3 PageHelper的基本使用流程

PageHelper 的使用流程主要包括分頁前的準(zhǔn)備、分頁方法的調(diào)用以及分頁結(jié)果的獲取。

3.3.1 分頁前的準(zhǔn)備工作

在調(diào)用分頁方法之前,必須先調(diào)用 PageHelper.startPage(pageNum, pageSize) 方法,該方法會(huì)設(shè)置當(dāng)前線程的分頁上下文。

import com.github.pagehelper.PageHelper;
import java.util.List;
public List<User> getUsers(int pageNum, int pageSize) {
    // 開啟分頁
    PageHelper.startPage(pageNum, pageSize);
    // 查詢用戶列表(自動(dòng)分頁)
    return userMapper.selectAll();
}

說明:

  • pageNum :當(dāng)前頁碼,從 1 開始。
  • pageSize :每頁顯示的數(shù)據(jù)條數(shù)。
  • 該方法必須在查詢語句之前調(diào)用,否則分頁失效。

3.3.2 分頁方法調(diào)用與結(jié)果返回

調(diào)用 PageHelper.startPage() 后,緊接著執(zhí)行查詢語句即可。PageHelper 會(huì)自動(dòng)攔截 SQL,并添加 LIMIT 子句實(shí)現(xiàn)分頁。

執(zhí)行查詢后,可以通過 PageInfo<T> 類封裝分頁信息:

import com.github.pagehelper.PageInfo;
public PageInfo<User> getUsers(int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<User> users = userMapper.selectAll();
    return new PageInfo<>(users);
}

PageInfo 包含了豐富的分頁信息,如總記錄數(shù)、當(dāng)前頁、總頁數(shù)等,便于前端展示。

3.3.3 常見配置參數(shù)的使用說明

參數(shù)作用使用示例
pageNum 當(dāng)前頁碼PageHelper.startPage(2, 10);
pageSize 每頁數(shù)量PageHelper.startPage(1, 20);
count 是否執(zhí)行 count 查詢默認(rèn)為 true,可通過 PageHelper.startPage(pageNum, pageSize, false) 關(guān)閉
reasonable 是否啟用合理化分頁在配置文件中設(shè)置為 true
pageSizeZero 是否允許 pageSize 為 0可設(shè)置為 true 表示不分頁
示例:關(guān)閉 count 查詢

在某些場景下,如果已知總記錄數(shù),可避免重復(fù)執(zhí)行 count 查詢:

PageHelper.startPage(1, 10, false);
List<User> users = userMapper.selectAll();

此時(shí) PageHelper 不會(huì)生成 count SQL,從而提高性能。

示例:分頁結(jié)果封裝為 PageInfo
PageInfo<User> pageInfo = new PageInfo<>(users);
System.out.println("當(dāng)前頁碼:" + pageInfo.getPageNum());
System.out.println("每頁數(shù)量:" + pageInfo.getPageSize());
System.out.println("總記錄數(shù):" + pageInfo.getTotal());
System.out.println("總頁數(shù):" + pageInfo.getPages());

輸出結(jié)果如下:

當(dāng)前頁碼:1
每頁數(shù)量:10
總記錄數(shù):123
總頁數(shù):13

流程圖:PageHelper分頁執(zhí)行流程
graph TD
    A[調(diào)用PageHelper.startPage] --> B{判斷是否合理化分頁}
    B -->|是| C[自動(dòng)調(diào)整頁碼]
    B -->|否| D[使用原始頁碼]
    C --> E[生成分頁SQL]
    D --> E
    E --> F[執(zhí)行SQL查詢]
    F --> G[返回分頁數(shù)據(jù)]
    G --> H[創(chuàng)建PageInfo對象]
    H --> I[返回給調(diào)用方]

該流程圖清晰地展示了 PageHelper 分頁的核心執(zhí)行流程,從開始分頁到最終封裝返回?cái)?shù)據(jù)的全過程。

通過本章的學(xué)習(xí),我們了解了 PageHelper 的功能與優(yōu)勢,掌握了其在 Maven 項(xiàng)目中的引入方式,以及在 MyBatis 和 Spring Boot 中的配置方法,并詳細(xì)講解了其基本使用流程及常見參數(shù)設(shè)置。下一章將圍繞 Mapper 接口設(shè)計(jì)分頁方法展開,進(jìn)一步深入 MyBatis 分頁的實(shí)踐應(yīng)用。

4. Mapper接口分頁方法設(shè)計(jì)

在 MyBatis 框架中,Mapper 接口是實(shí)現(xiàn)數(shù)據(jù)庫操作的核心部分。設(shè)計(jì)良好的 Mapper 接口不僅能夠提高代碼的可維護(hù)性,還能有效支持分頁查詢功能。本章將深入探討 Mapper 接口中分頁方法的設(shè)計(jì)規(guī)范、分頁 SQL 的編寫與優(yōu)化策略,以及接口測試與驗(yàn)證方法,幫助開發(fā)者構(gòu)建高效、穩(wěn)定的分頁機(jī)制。

4.1 Mapper接口的設(shè)計(jì)規(guī)范

4.1.1 接口命名與SQL映射關(guān)系

在設(shè)計(jì) Mapper 接口時(shí),良好的命名規(guī)范有助于提高代碼的可讀性和維護(hù)性。通常建議使用 IEntityMapper 的命名方式,其中 Entity 表示操作的實(shí)體對象,例如 IUserMapper 、 IOrderMapper 。

接口中的方法名應(yīng)與 XML 映射文件中的 SQL ID 保持一致,以確保 MyBatis 能正確綁定方法與 SQL 語句。例如:

public interface IUserMapper {
    List<User> selectAllUsers();
}

對應(yīng)的 XML 文件中:

<select id="selectAllUsers" resultType="User">
    SELECT * FROM users
</select>

這種命名方式不僅提高了代碼的可讀性,也便于后期維護(hù)和調(diào)試。

4.1.2 使用PageHelper進(jìn)行分頁的方法定義

在使用 PageHelper 插件進(jìn)行分頁時(shí),Mapper 接口中的方法設(shè)計(jì)需遵循一定的規(guī)范。PageHelper 通過攔截查詢語句,自動(dòng)為其添加分頁邏輯,因此接口方法只需返回 List<T> 類型即可,PageHelper 會(huì)在執(zhí)行過程中自動(dòng)封裝分頁信息。

示例代碼如下:

public interface IUserMapper {
    List<User> selectAllUsers();
}

在調(diào)用該方法前,需先調(diào)用 PageHelper.startPage(pageNum, pageSize) 方法啟動(dòng)分頁:

PageHelper.startPage(1, 10);
List<User> users = userMapper.selectAllUsers();

PageHelper 會(huì)自動(dòng)對 selectAllUsers() 方法的查詢結(jié)果進(jìn)行分頁處理,并封裝成 PageInfo 對象,便于后續(xù)使用。

4.2 分頁SQL語句的編寫與優(yōu)化

4.2.1 動(dòng)態(tài)SQL與分頁結(jié)合使用

在實(shí)際開發(fā)中,經(jīng)常需要根據(jù)不同的條件進(jìn)行分頁查詢。MyBatis 提供了 <if> 、 <choose> <where> 等標(biāo)簽,用于構(gòu)建動(dòng)態(tài) SQL,從而實(shí)現(xiàn)靈活的查詢邏輯。

例如,以下是一個(gè)帶有動(dòng)態(tài)查詢條件的分頁 SQL 示例:

<select id="selectUsersByCondition" resultType="User">
    SELECT * FROM users
    <where>
        <if test="username != null and username != ''">
            AND username LIKE CONCAT('%', #{username}, '%')
        </if>
        <if test="email != null and email != ''">
            AND email = #{email}
        </if>
    </where>
</select>

在 Java 代碼中調(diào)用:

PageHelper.startPage(1, 10);
List<User> users = userMapper.selectUsersByCondition("john", null);

該查詢會(huì)根據(jù)傳入的參數(shù)動(dòng)態(tài)生成 SQL,確保分頁結(jié)果的準(zhǔn)確性。

4.2.2 分頁SQL的性能考量與優(yōu)化技巧

分頁查詢在處理大數(shù)據(jù)量時(shí)容易造成性能問題。以下是一些常見的優(yōu)化技巧:

  1. 避免使 SELECT * :指定查詢字段,減少不必要的數(shù)據(jù)傳輸。
  2. 使用索引 :確保分頁字段(如主鍵或常用查詢字段)上有合適的索引。
  3. 避免深分頁問題 :對于 LIMIT offset, size 這種方式,當(dāng) offset 值很大時(shí)會(huì)導(dǎo)致性能下降,建議采用“游標(biāo)分頁”或“基于時(shí)間戳”的方式。
  4. 合理設(shè)置分頁大小 :避免一次請求返回過多數(shù)據(jù),建議每頁 10~50 條為宜。

示例優(yōu)化后的 SQL:

<select id="selectUsersByCondition" resultType="User">
    SELECT id, username, email FROM users
    <where>
        <if test="username != null and username != ''">
            AND username LIKE CONCAT('%', #{username}, '%')
        </if>
        <if test="email != null and email != ''">
            AND email = #{email}
        </if>
    </where>
</select>

通過指定字段查詢,減少數(shù)據(jù)庫 IO 消耗,提升查詢效率。

4.3 分頁接口的測試與驗(yàn)證

4.3.1 單元測試的設(shè)計(jì)與執(zhí)行

為了確保分頁接口的正確性和穩(wěn)定性,必須進(jìn)行充分的單元測試??梢允褂?JUnit 框架結(jié)合 Spring Boot Test 進(jìn)行測試。

示例單元測試代碼如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
    @Autowired
    private IUserMapper userMapper;
    @Test
    public void testSelectUsersWithPagination() {
        PageHelper.startPage(1, 10);
        List<User> users = userMapper.selectAllUsers();
        Assert.notEmpty(users, "用戶列表不能為空");
        Assert.isTrue(users.size() <= 10, "返回結(jié)果數(shù)量不應(yīng)超過每頁限制");
    }
}

該測試方法驗(yàn)證了分頁查詢是否返回了正確的數(shù)據(jù)量,并確保接口邏輯無誤。

4.3.2 分頁結(jié)果的驗(yàn)證與異常處理

在實(shí)際運(yùn)行中,可能會(huì)出現(xiàn)分頁失敗、SQL 錯(cuò)誤等情況。因此,在測試中還需驗(yàn)證異常處理邏輯。

例如,測試當(dāng)傳入非法頁碼時(shí)是否拋出異常:

@Test(expected = RuntimeException.class)
public void testInvalidPageNumber() {
    PageHelper.startPage(-1, 10); // 無效頁碼
    userMapper.selectAllUsers();
}

此外,還可以通過日志記錄、異常捕獲等方式進(jìn)行異常處理,提升系統(tǒng)的健壯性。

附錄:分頁流程圖

以下是分頁查詢在 MyBatis 中的完整執(zhí)行流程圖:

graph TD
    A[調(diào)用Mapper方法] --> B{PageHelper是否啟動(dòng)}
    B -->|是| C[攔截SQL并添加分頁語句]
    C --> D[執(zhí)行SQL查詢]
    D --> E[封裝結(jié)果為PageInfo]
    B -->|否| F[直接執(zhí)行SQL查詢]
    F --> G[返回原始結(jié)果]

該流程圖清晰地展示了 PageHelper 在分頁查詢中的作用機(jī)制,有助于理解其工作原理。

小結(jié)

本章詳細(xì)介紹了在 MyBatis 中設(shè)計(jì) Mapper 接口進(jìn)行分頁查詢的方法,包括接口命名規(guī)范、PageHelper 的使用方式、動(dòng)態(tài) SQL 的編寫與優(yōu)化技巧,以及接口的測試與異常處理。通過本章的學(xué)習(xí),開發(fā)者可以掌握如何在實(shí)際項(xiàng)目中高效地實(shí)現(xiàn)分頁功能,并優(yōu)化其性能表現(xiàn)。

5. Service層分頁邏輯實(shí)現(xiàn)

在Spring Boot架構(gòu)中,Service層承擔(dān)著核心業(yè)務(wù)邏輯的處理職責(zé)。在分頁查詢場景下,Service層不僅要協(xié)調(diào)Mapper層的數(shù)據(jù)獲取,還需對分頁結(jié)果進(jìn)行封裝與處理。本章將從Service層的分頁邏輯設(shè)計(jì)、數(shù)據(jù)封裝方式、異常處理機(jī)制等方面深入探討,并通過代碼實(shí)例展示完整的實(shí)現(xiàn)流程。

5.1 Service層職責(zé)與分頁邏輯設(shè)計(jì)

Service層作為連接Controller與Mapper的橋梁,其設(shè)計(jì)直接影響分頁查詢的性能與可維護(hù)性。合理的邏輯設(shè)計(jì)能夠提高系統(tǒng)的可擴(kuò)展性與健壯性。

5.1.1 業(yè)務(wù)邏輯與分頁的結(jié)合方式

在企業(yè)級應(yīng)用中,分頁查詢往往不是單純的數(shù)據(jù)庫查詢,而是需要結(jié)合業(yè)務(wù)規(guī)則進(jìn)行過濾、排序或聚合。例如,在用戶管理模塊中,可能需要根據(jù)角色、狀態(tài)等條件進(jìn)行篩選后再分頁。

public interface UserService {
    PageInfo<UserDTO> getUsersByRoleAndStatus(String role, String status, int pageNum, int pageSize);
}

在該接口中, role status 是業(yè)務(wù)篩選條件, pageNum pageSize 用于分頁控制。Service層通過組合這些參數(shù)調(diào)用Mapper層的查詢接口。

分頁邏輯流程圖(Mermaid格式)
graph TD
    A[Controller層接收請求] --> B[調(diào)用Service層方法]
    B --> C[Service層封裝參數(shù)]
    C --> D[調(diào)用PageHelper.startPage()]
    D --> E[執(zhí)行Mapper層查詢]
    E --> F[封裝PageInfo對象]
    F --> G[返回分頁結(jié)果]

5.1.2 調(diào)用Mapper接口實(shí)現(xiàn)分頁查詢

Service層調(diào)用Mapper接口前,需使用PageHelper插件開啟分頁功能。以下是一個(gè)典型的調(diào)用示例:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public PageInfo<UserDTO> getUsersByRoleAndStatus(String role, String status, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<UserDTO> users = userMapper.selectByRoleAndStatus(role, status);
        return new PageInfo<>(users);
    }
}
代碼逐行分析:
  • 第7行 :注入U(xiǎn)serMapper,用于執(zhí)行數(shù)據(jù)庫查詢。
  • 第11行 :調(diào)用 PageHelper.startPage() 方法,指定當(dāng)前頁碼和每頁記錄數(shù)。
  • 第12行 :調(diào)用Mapper接口的查詢方法,返回當(dāng)前頁的數(shù)據(jù)列表。
  • 第13行 :使用MyBatis PageHelper提供的PageInfo類封裝分頁信息,包括總記錄數(shù)、總頁數(shù)、當(dāng)前頁數(shù)據(jù)等。

5.2 分頁數(shù)據(jù)的處理與封裝

分頁查詢的結(jié)果通常包含當(dāng)前頁數(shù)據(jù)、總記錄數(shù)、頁碼信息等。Service層需對這些數(shù)據(jù)進(jìn)行封裝,并可能附加業(yè)務(wù)邏輯處理。

5.2.1 PageInfo對象的封裝過程

PageInfo是PageHelper提供的分頁信息封裝類,包含以下核心字段:

字段名類型說明
pageNumint當(dāng)前頁碼
pageSizeint每頁記錄數(shù)
sizeint當(dāng)前頁實(shí)際記錄數(shù)
totallong總記錄數(shù)
pagesint總頁數(shù)
listList當(dāng)前頁的數(shù)據(jù)列表
isFirstPageboolean是否為第一頁
isLastPageboolean是否為最后一頁
封裝示例:
PageInfo<UserDTO> pageInfo = new PageInfo<>(users);

該語句自動(dòng)計(jì)算出總頁數(shù)、是否為首頁/尾頁等信息,開發(fā)者可直接使用這些字段進(jìn)行頁面展示。

5.2.2 分頁數(shù)據(jù)的業(yè)務(wù)處理邏輯

在實(shí)際業(yè)務(wù)中,分頁結(jié)果可能需要進(jìn)行額外處理,例如:

  • 數(shù)據(jù)轉(zhuǎn)換:將數(shù)據(jù)庫實(shí)體轉(zhuǎn)換為DTO(數(shù)據(jù)傳輸對象)。
  • 數(shù)據(jù)脫敏:對敏感字段進(jìn)行隱藏或加密。
  • 數(shù)據(jù)聚合:對查詢結(jié)果進(jìn)行統(tǒng)計(jì)或分組。

以下是一個(gè)帶有數(shù)據(jù)轉(zhuǎn)換與脫敏處理的示例:

@Override
public PageInfo<UserDTO> getUsersByRoleAndStatus(String role, String status, int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<User> users = userMapper.selectByRoleAndStatus(role, status);
    // 數(shù)據(jù)轉(zhuǎn)換與脫敏
    List<UserDTO> dtoList = users.stream()
        .map(user -> {
            UserDTO dto = new UserDTO();
            dto.setId(user.getId());
            dto.setUsername(user.getUsername());
            dto.setEmail("****@example.com"); // 脫敏處理
            return dto;
        })
        .collect(Collectors.toList());
    return new PageInfo<>(dtoList);
}
代碼邏輯說明:
  • 第6~13行 :將User實(shí)體轉(zhuǎn)換為UserDTO,并對email字段進(jìn)行脫敏處理。
  • 第14行 :封裝為PageInfo對象,便于Controller層返回。

5.3 Service層的異常處理與日志記錄

在分頁操作中,可能出現(xiàn)SQL執(zhí)行異常、參數(shù)校驗(yàn)失敗、空指針等錯(cuò)誤。良好的異常處理機(jī)制與日志記錄策略有助于快速定位問題。

5.3.1 分頁失敗的異常處理策略

建議使用Spring的全局異常處理器統(tǒng)一處理異常,以下為Service層的局部處理示例:

@Override
public PageInfo<UserDTO> getUsersByRoleAndStatus(String role, String status, int pageNum, int pageSize) {
    try {
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectByRoleAndStatus(role, status);
        return new PageInfo<>(convertToDTO(users));
    } catch (Exception e) {
        // 捕獲異常并封裝為業(yè)務(wù)異常
        throw new BusinessException("分頁查詢失?。? + e.getMessage(), e);
    }
}
異常處理流程圖(Mermaid格式)
graph TD
    A[Service層執(zhí)行分頁] --> B{是否發(fā)生異常?}
    B -->|是| C[捕獲異常]
    C --> D[封裝為業(yè)務(wù)異常]
    D --> E[拋出異常]
    B -->|否| F[正常返回PageInfo]

5.3.2 日志記錄與問題定位技巧

建議在Service層引入日志記錄器(如Logback、SLF4J),記錄關(guān)鍵參數(shù)和執(zhí)行結(jié)果:

private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Override
public PageInfo<UserDTO> getUsersByRoleAndStatus(String role, String status, int pageNum, int pageSize) {
    logger.info("開始分頁查詢,角色:{}, 狀態(tài):{}, 當(dāng)前頁:{}, 每頁記錄數(shù):{}", role, status, pageNum, pageSize);
    try {
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectByRoleAndStatus(role, status);
        PageInfo<UserDTO> pageInfo = new PageInfo<>(convertToDTO(users));
        logger.info("分頁查詢成功,總記錄數(shù):{}", pageInfo.getTotal());
        return pageInfo;
    } catch (Exception e) {
        logger.error("分頁查詢失?。?, e);
        throw new BusinessException("分頁查詢失?。? + e.getMessage(), e);
    }
}
日志輸出示例:
INFO  UserServiceImpl - 開始分頁查詢,角色:admin, 狀態(tài):active, 當(dāng)前頁:1, 每頁記錄數(shù):10
INFO  UserServiceImpl - 分頁查詢成功,總記錄數(shù):50
日志記錄建議:
  • 記錄請求參數(shù)、分頁參數(shù)、執(zhí)行結(jié)果等關(guān)鍵信息。
  • 使用結(jié)構(gòu)化日志格式(如JSON)便于日志分析系統(tǒng)解析。
  • 在異常發(fā)生時(shí),記錄堆棧信息以便快速定位問題。

本章系統(tǒng)講解了Service層在分頁查詢中的核心職責(zé),包括分頁邏輯設(shè)計(jì)、數(shù)據(jù)封裝方式以及異常處理與日志記錄策略。通過代碼實(shí)例與流程圖的結(jié)合,展示了如何在實(shí)際開發(fā)中高效實(shí)現(xiàn)分頁功能,并確保系統(tǒng)的穩(wěn)定性與可維護(hù)性。下一章將重點(diǎn)介紹Controller層如何接收分頁請求并返回統(tǒng)一格式的響應(yīng)。

6. Controller層接口接收與返回處理

在基于MyBatis和PageHelper構(gòu)建的分頁系統(tǒng)中,Controller層作為前后端交互的核心環(huán)節(jié),承擔(dān)著接收請求參數(shù)、調(diào)用業(yè)務(wù)邏輯并返回結(jié)構(gòu)化響應(yīng)的關(guān)鍵任務(wù)。本章將深入探討Controller層接口設(shè)計(jì)的規(guī)范、分頁數(shù)據(jù)的返回格式設(shè)計(jì),并結(jié)合實(shí)際代碼示例說明如何通過接口測試工具(如Postman)進(jìn)行調(diào)試和問題排查。

6.1 Controller層的接口設(shè)計(jì)原則

在Spring Boot框架中,Controller層主要通過 @RestController 注解實(shí)現(xiàn),其設(shè)計(jì)需遵循RESTful風(fēng)格,同時(shí)兼顧接口的健壯性和可維護(hù)性。

6.1.1 接口路徑與請求方式的定義

接口路徑的設(shè)計(jì)應(yīng)遵循清晰、簡潔的原則,通常以名詞復(fù)數(shù)形式表示資源集合。例如:

@GetMapping("/users")
public PageInfo<User> getUsers(@RequestParam int pageNum, @RequestParam int pageSize) {
    return userService.getUsersByPage(pageNum, pageSize);
}
  • 請求方式 :GET 用于獲取資源,POST 用于提交數(shù)據(jù)。
  • 路徑命名 /users 表示用戶資源, /orders 表示訂單資源,遵循小寫復(fù)數(shù)命名。
  • 版本控制 :建議在URL中加入版本號,如 /v1/users ,便于后續(xù)接口升級。

6.1.2 請求參數(shù)的接收與校驗(yàn)機(jī)制

Controller層接收參數(shù)時(shí),應(yīng)進(jìn)行基本的校驗(yàn),防止非法輸入導(dǎo)致系統(tǒng)異常。Spring Boot提供了 @Valid 注解結(jié)合 javax.validation 實(shí)現(xiàn)參數(shù)校驗(yàn)。

示例:帶參數(shù)校驗(yàn)的分頁接口
@RestController
@RequestMapping("/v1/users")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping
    public ResponseEntity<PageInfo<User>> getUsers(
            @RequestParam @Min(1) int pageNum,
            @RequestParam @Min(1) @Max(100) int pageSize) {
        PageInfo<User> pageInfo = userService.getUsersByPage(pageNum, pageSize);
        return ResponseEntity.ok(pageInfo);
    }
}
  • @Min(1) :確保頁碼至少為1。
  • @Max(100) :限制每頁最多100條數(shù)據(jù),防止性能問題。
  • 使用 ResponseEntity 封裝響應(yīng),增強(qiáng)接口返回的可擴(kuò)展性。

6.2 分頁數(shù)據(jù)的返回格式設(shè)計(jì)

為了前后端交互的一致性和統(tǒng)一性,Controller層返回的分頁數(shù)據(jù)應(yīng)具備標(biāo)準(zhǔn)化結(jié)構(gòu),通常采用JSON格式,并封裝統(tǒng)一的響應(yīng)對象。

6.2.1 JSON格式的封裝與統(tǒng)一返回

建議使用統(tǒng)一的響應(yīng)封裝類 ResponseResult ,其結(jié)構(gòu)如下:

public class ResponseResult<T> {
    private int code;
    private String message;
    private T data;

    // 構(gòu)造方法、getters、setters
}

結(jié)合PageInfo返回:

@GetMapping
public ResponseResult<PageInfo<User>> getUsers(
        @RequestParam @Min(1) int pageNum,
        @RequestParam @Min(1) @Max(100) int pageSize) {
    PageInfo<User> pageInfo = userService.getUsersByPage(pageNum, pageSize);
    return ResponseResult.success(pageInfo);
}
響應(yīng)示例:
{
  "code": 200,
  "message": "操作成功",
  "data": {
    "pageNum": 1,
    "pageSize": 10,
    "total": 150,
    "pages": 15,
    "list": [
      {"id": 1, "name": "張三", "email": "zhangsan@example.com"},
      ...
    ]
  }
}
  • code :狀態(tài)碼,如200表示成功。
  • message :描述性信息,便于調(diào)試。
  • data :封裝分頁數(shù)據(jù)對象 PageInfo 。

6.2.2 PageInfo對象在接口中的返回結(jié)構(gòu)

PageInfo 對象是PageHelper提供的分頁結(jié)果封裝類,包含以下核心字段:

字段名類型描述
pageNumint當(dāng)前頁碼
pageSizeint每頁數(shù)量
totallong總記錄數(shù)
pagesint總頁數(shù)
listList當(dāng)前頁的數(shù)據(jù)集合
isFirstPageboolean是否為首頁
isLastPageboolean是否為尾頁

mermaid流程圖:Controller層數(shù)據(jù)流向

graph TD
    A[前端請求] --> B[Controller接收參數(shù)]
    B --> C{參數(shù)校驗(yàn)是否通過?}
    C -->|是| D[調(diào)用Service獲取PageInfo]
    D --> E[封裝ResponseResult]
    E --> F[返回JSON格式數(shù)據(jù)]
    C -->|否| G[返回錯(cuò)誤信息]

6.3 接口測試與調(diào)試

接口開發(fā)完成后,必須進(jìn)行充分的測試與調(diào)試,確保分頁邏輯正確、數(shù)據(jù)返回格式一致、異常處理得當(dāng)。

6.3.1 Postman測試接口的使用

使用Postman可以快速測試RESTful接口,以下是測試步驟:

  1. 打開Postman ,新建請求。
  2. 設(shè)置請求方式 :GET。
  3. 輸入請求地址 :例如 http://localhost:8080/v1/users?pageNum=1&pageSize=10
  4. 發(fā)送請求 ,查看返回的JSON結(jié)構(gòu)是否符合預(yù)期。
  5. 測試異常情況 :如 pageNum=0 、 pageSize=200 ,驗(yàn)證是否返回400錯(cuò)誤及提示信息。
示例截圖說明(文字描述)

假設(shè)Postman界面左側(cè)為請求輸入?yún)^(qū)域,輸入U(xiǎn)RL和參數(shù)后點(diǎn)擊“Send”按鈕,右側(cè)顯示響應(yīng)結(jié)果。響應(yīng)體應(yīng)包含完整的PageInfo數(shù)據(jù)結(jié)構(gòu),并且狀態(tài)碼為200或400。

6.3.2 接口調(diào)用過程中的問題排查

常見問題及排查方法如下:

問題現(xiàn)象原因分析解決方法
返回?cái)?shù)據(jù)為空SQL語句錯(cuò)誤、PageHelper未生效檢查SQL是否執(zhí)行,日志輸出是否開啟
分頁不準(zhǔn)確pageNum或pageSize參數(shù)傳遞錯(cuò)誤添加參數(shù)校驗(yàn),確保參數(shù)合法
接口響應(yīng)超時(shí)數(shù)據(jù)量過大或SQL未優(yōu)化檢查SQL執(zhí)行計(jì)劃,添加索引,優(yōu)化查詢語句
PageInfo字段缺失或異常PageHelper版本兼容性問題升級PageHelper版本,或更換Spring Boot版本
示例:日志輸出輔助調(diào)試

在Spring Boot中啟用SQL日志輸出:

# application.yml
logging:
  level:
    com.example.mapper: debug

輸出示例:

DEBUG  c.e.m.UserMapper.getUsersByPage - ==>  Preparing: SELECT * FROM users LIMIT 0,10
DEBUG  c.e.m.UserMapper.getUsersByPage - ==> Parameters: 
DEBUG  c.e.m.UserMapper.getUsersByPage - <==      Total: 10

通過日志可以確認(rèn)分頁是否生效,SQL是否被PageHelper攔截并修改。

本章從Controller層接口設(shè)計(jì)原則出發(fā),深入講解了分頁接口的路徑定義、參數(shù)接收與校驗(yàn)機(jī)制,并詳細(xì)說明了如何設(shè)計(jì)統(tǒng)一的JSON返回格式。通過引入 ResponseResult PageInfo 對象,實(shí)現(xiàn)結(jié)構(gòu)化數(shù)據(jù)返回。最后,結(jié)合Postman測試與常見問題排查技巧,幫助開發(fā)者高效完成接口調(diào)試與問題定位。

7. PageInfo對象使用詳解

7.1 PageInfo對象的結(jié)構(gòu)與屬性

PageInfo 是 PageHelper 提供的一個(gè)分頁數(shù)據(jù)封裝類,它封裝了當(dāng)前頁的數(shù)據(jù)信息以及與分頁相關(guān)的各種元數(shù)據(jù)。在使用 PageHelper 進(jìn)行分頁查詢后,通過調(diào)用 PageHelper.startPage() 方法后緊跟查詢語句,會(huì)自動(dòng)將結(jié)果封裝為 PageInfo 對象。

7.1.1 PageInfo類的核心字段說明

PageInfo 類包含以下常用字段:

字段名類型描述
pageNumint當(dāng)前頁碼
pageSizeint每頁記錄數(shù)
sizeint當(dāng)前頁的實(shí)際數(shù)據(jù)條數(shù)
startRowint當(dāng)前頁第一個(gè)數(shù)據(jù)的行號
endRowint當(dāng)前頁最后一個(gè)數(shù)據(jù)的行號
totallong總記錄數(shù)
pagesint總頁數(shù)
listList<?>當(dāng)前頁的數(shù)據(jù)集合
prePageint上一頁頁碼
nextPageint下一頁頁碼
isFirstPageboolean是否為第一頁
isLastPageboolean是否為最后一頁
hasPreviousPageboolean是否存在上一頁
hasNextPageboolean是否存在下一頁

7.1.2 分頁信息的封裝過程

在 Service 層調(diào)用 Mapper 查詢后,PageHelper 會(huì)自動(dòng)將查詢結(jié)果封裝成 PageInfo 對象。例如:

PageHelper.startPage(pageNum, pageSize);  // 設(shè)置分頁參數(shù)
List<User> users = userMapper.selectAll(); // 執(zhí)行查詢
PageInfo<User> pageInfo = new PageInfo<>(users); // 封裝成PageInfo

上述代碼中, PageHelper.startPage() 會(huì)攔截下一條 SQL 查詢,并自動(dòng)添加分頁邏輯。查詢結(jié)果通過 PageInfo 構(gòu)造函數(shù)進(jìn)行封裝,返回包含完整分頁信息的對象。

7.2 PageInfo在前端展示中的應(yīng)用

7.2.1 前端頁面獲取與解析PageInfo數(shù)據(jù)

在前后端分離架構(gòu)中,Controller 層通常會(huì)將 PageInfo 對象以 JSON 格式返回給前端。例如:

@GetMapping("/users")
public ResponseEntity<PageInfo<User>> getUsers(@RequestParam int pageNum, @RequestParam int pageSize) {
    PageInfo<User> pageInfo = userService.getUsers(pageNum, pageSize);
    return ResponseEntity.ok(pageInfo);
}

前端(如 Vue、React、Angular 等框架)接收到數(shù)據(jù)后,可以輕松解析并展示分頁信息:

fetch(`/api/users?pageNum=1&pageSize=10`)
  .then(response => response.json())
  .then(data => {
    console.log('當(dāng)前頁碼:', data.pageNum);
    console.log('總頁數(shù):', data.pages);
    console.log('用戶列表:', data.list);
  });

7.2.2 分頁控件的動(dòng)態(tài)渲染與交互邏輯

前端可以基于 PageInfo 中的 pageNum 、 pages 、 hasPreviousPage hasNextPage 等字段來動(dòng)態(tài)渲染分頁控件,并實(shí)現(xiàn)跳轉(zhuǎn)邏輯。

例如,使用 Vue 渲染一個(gè)簡單的分頁組件:

<template>
  <div class="pagination">
    <button :disabled="!pageInfo.hasPreviousPage" @click="prevPage">上一頁</button>
    <span>當(dāng)前頁:{{ pageInfo.pageNum }} / {{ pageInfo.pages }}</span>
    <button :disabled="!pageInfo.hasNextPage" @click="nextPage">下一頁</button>
  </div>
</template>
<script>
export default {
  props: ['pageInfo'],
  methods: {
    prevPage() {
      this.$emit('change-page', this.pageInfo.pageNum - 1);
    },
    nextPage() {
      this.$emit('change-page', this.pageInfo.pageNum + 1);
    }
  }
}
</script>

通過監(jiān)聽按鈕點(diǎn)擊事件并重新請求對應(yīng)頁碼的數(shù)據(jù),實(shí)現(xiàn)頁面切換。

7.3 PageInfo的擴(kuò)展與自定義封裝

7.3.1 自定義分頁對象的封裝方式

雖然 PageInfo 已經(jīng)提供了豐富的字段,但在某些業(yè)務(wù)場景中,可能需要額外的字段或更靈活的數(shù)據(jù)結(jié)構(gòu)。此時(shí)可以自定義一個(gè)分頁響應(yīng)類來封裝 PageInfo 的數(shù)據(jù)。

例如:

public class CustomPageResponse<T> {
    private int currentPage;
    private int pageSize;
    private long totalElements;
    private int totalPages;
    private List<T> content;
    private boolean hasNext;
    private boolean hasPrevious;
    public static <T> CustomPageResponse<T> fromPageInfo(PageInfo<T> pageInfo) {
        CustomPageResponse<T> response = new CustomPageResponse<>();
        response.setCurrentPage(pageInfo.getPageNum());
        response.setPageSize(pageInfo.getPageSize());
        response.setTotalElements(pageInfo.getTotal());
        response.setTotalPages(pageInfo.getPages());
        response.setContent(pageInfo.getList());
        response.setHasNext(pageInfo.isHasNextPage());
        response.setHasPrevious(pageInfo.isHasPreviousPage());
        return response;
    }
    // Getters and Setters
}

在 Controller 中返回該對象:

@GetMapping("/users")
public ResponseEntity<CustomPageResponse<User>> getUsers(@RequestParam int pageNum, @RequestParam int pageSize) {
    PageInfo<User> pageInfo = userService.getUsers(pageNum, pageSize);
    CustomPageResponse<User> response = CustomPageResponse.fromPageInfo(pageInfo);
    return ResponseEntity.ok(response);
}

7.3.2 PageInfo與其他業(yè)務(wù)對象的整合使用

在實(shí)際業(yè)務(wù)中,分頁信息可能需要與其它數(shù)據(jù)(如統(tǒng)計(jì)數(shù)據(jù)、篩選條件、權(quán)限信息等)一起返回。此時(shí)可以將 PageInfo 作為響應(yīng)對象的一個(gè)字段進(jìn)行封裝。

例如:

public class UserPageResponse {
    private PageInfo<User> pageInfo;
    private int activeUserCount;
    private int totalUserCount;

    // 構(gòu)造方法、Getters、Setters
}

Controller 返回示例:

@GetMapping("/users")
public ResponseEntity<UserPageResponse> getUsers(@RequestParam int pageNum, @RequestParam int pageSize) {
    PageInfo<User> pageInfo = userService.getUsers(pageNum, pageSize);
    int activeCount = userService.getActiveUserCount();
    int totalCount = pageInfo.getTotal();

    UserPageResponse response = new UserPageResponse();
    response.setPageInfo(pageInfo);
    response.setActiveUserCount(activeCount);
    response.setTotalUserCount(totalCount);

    return ResponseEntity.ok(response);
}

這樣,前端可以在獲取分頁數(shù)據(jù)的同時(shí),也獲得其他業(yè)務(wù)信息,提升接口的靈活性和復(fù)用性。

到此這篇關(guān)于MyBatis分頁查詢實(shí)戰(zhàn)案例詳解的文章就介紹到這了,更多相關(guān)MyBatis分頁查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

宽甸| 沙坪坝区| 秦皇岛市| 云霄县| 内丘县| 郧西县| 冕宁县| 大同市| 桦川县| 余姚市| 巢湖市| 中牟县| 铜川市| 洛南县| 泰来县| 泊头市| 达日县| 台湾省| 永吉县| 昭觉县| 龙门县| 贞丰县| 崇阳县| 信宜市| 汽车| 云南省| 景德镇市| 石门县| 曲松县| 桂东县| 化隆| 阿拉善左旗| 河间市| 香格里拉县| 呼图壁县| 洪雅县| 吉林省| 江油市| 穆棱市| 扶沟县| 宁波市|