分頁查詢
public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {PageHelper.startPage(categoryPageQueryDTO.getPage(),categoryPageQueryDTO.getPageSize());//下一條sql進行分頁,自動加入limit關鍵字分頁Page<Category> page = categoryMapper.pageQuery(categoryPageQueryDTO);return new PageResult(page.getTotal(), page.getResult());}
這段 Java 代碼是一個典型的 分頁查詢方法,使用了 PageHelper(MyBatis 的分頁插件)和 MyBatis 的 Mapper 接口 來實現分頁查詢功能。
🧩 一、代碼逐行解析
public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {
- 定義一個名為
pageQuery
的方法,接收一個CategoryPageQueryDTO
類型的參數,返回值為PageResult
。 CategoryPageQueryDTO
是封裝分頁查詢參數的 數據傳輸對象(DTO)。PageResult
是一個封裝了分頁結果(總記錄數和當前頁數據)的響應對象。
PageHelper.startPage(categoryPageQueryDTO.getPage(), categoryPageQueryDTO.getPageSize());
- 這是 PageHelper 提供的靜態方法,用于開啟分頁功能。
- 它會攔截下一條 SQL 查詢,并自動為其加上分頁語句(如
LIMIT offset, pageSize
)。 - 參數說明:
getPage()
:當前頁碼(如第1頁、第2頁)getPageSize()
:每頁顯示的記錄數
?? 注意:
PageHelper.startPage()
只對緊隨其后的第一條查詢語句生效,所以一定要確保它在執行查詢前調用。
Page<Category> page = categoryMapper.pageQuery(categoryPageQueryDTO);
- 調用
categoryMapper
的pageQuery
方法執行數據庫查詢。 - 返回值類型是
Page<Category>
,這是 PageHelper 提供的一個分頁對象,內部封裝了:- 當前頁的數據(
List<Category>
) - 總記錄數(
total
) - 當前頁碼、每頁大小等信息(PageHelper 內部使用)
- 當前頁的數據(
return new PageResult(page.getTotal(), page.getResult());
- 構造一個
PageResult
對象返回給前端:page.getTotal()
:總記錄數page.getResult()
:當前頁的數據列表(List<Category>
)
🧾 二、涉及類說明
1. PageHelper.startPage(...)
(MyBatis 分頁插件)
- 來自:
com.github.pagehelper.PageHelper
- 功能:開啟分頁,自動為下一條 SQL 添加分頁邏輯。
- 依賴:需要在項目中引入
pagehelper-spring-boot-starter
或手動配置插件。
2. Page<T>
(MyBatis 分頁結果對象)
- 來自:
com.github.pagehelper.Page
- 是一個
List<T>
的子類,額外封裝了分頁信息,如:long getTotal()
:總記錄數int getPageNum()
:當前頁碼int getPageSize()
:每頁大小
3. CategoryPageQueryDTO
- 是一個自定義的 查詢參數封裝類,通常包含如下字段:
@Datapublic class CategoryPageQueryDTO implements Serializable {//頁碼private int page;//每頁記錄數private int pageSize;//分類名稱private String name;//分類類型 1菜品分類 2套餐分類private Integer type;}
4. PageResult
- 是一個通用的分頁結果封裝類,通常用于返回給前端,結構如下:
@Data @AllArgsConstructor @NoArgsConstructor public class PageResult {private long total; // 總記錄數private List<?> records; // 當前頁數據 }
📌 三、MyBatis Mapper 接口示例
public interface CategoryMapper {Page<Category> pageQuery(CategoryPageQueryDTO categoryPageQueryDTO);
}
對應的 XML SQL 示例:
<!-- 分頁查詢--><select id="pageQuery" resultType="com.sky.entity.Category">select * from category<where><if test="name != null and name != ''">and name like concat('%',#{name},'%')</if><if test="type != null">and type = #{type}</if></where>order by sort asc , create_time desc</select>
? 四、總結流程圖
1. 接口接收分頁參數 (Page, PageSize)↓
2. 調用 PageHelper.startPage(page, pageSize)↓
3. 執行 categoryMapper.pageQuery(dto) 查詢↓
4. MyBatis + PageHelper 自動添加 LIMIT 分頁語句↓
5. 查詢結果返回 Page<Category> 對象↓
6. 構造 PageResult 返回給前端
? 五、注意事項
-
PageHelper 僅對下一條 SQL 生效
- 如果中間有其他 SQL 被執行,分頁可能失效。
- 例如:在
startPage()
后又執行了select count(*)
,再執行主查詢,可能導致分頁失效。
-
不要在循環中使用 PageHelper
- 可能導致分頁混亂。
-
PageHelper 與 MyBatis Plus 的 Page 對象不同
- MyBatis Plus 使用
IPage
,PageHelper 使用Page
,注意不要混淆。
- MyBatis Plus 使用
? 六、推薦優化:使用 PageResult 封裝更豐富的信息
public class PageResult {private long total;private int pageNum;private int pageSize;private int totalPages;private List<?> records;public PageResult(long total, List<?> records, int pageNum, int pageSize) {this.total = total;this.records = records;this.pageNum = pageNum;this.pageSize = pageSize;this.totalPages = (int) Math.ceil((double) total / pageSize);}// Getter / Setter
}
這樣前端可以拿到:
- 總頁數
- 當前頁
- 每頁數量
- 數據列表