SpringBoot中分頁外掛PageHelper的使用

chuimber發表於2024-05-02

SpringBoot如何使用PageHelper實現分頁查詢

在原始的分頁查詢方法中,需要編寫複雜的SQL語句來限制查詢結果的範圍,通常需要使用LIMIT或者ROWNUM等資料庫特定的語法來實現分頁。在每個需要分頁的查詢方法中,都需要手動計算分頁的起始位置和偏移量,通常需要根據頁碼和每頁數量來計算,這部分程式碼會在不同的查詢方法中重複出現。

原始分頁方法

  1. Controller
    //原始分頁方法
    @GetMapping("/chapter01/primitive")
    public List<UserEntity> chapter01(@RequestParam Integer pageNum, @RequestParam Integer pageSize){
        HashMap<String,Integer> map = new HashMap<>();
        map.put("offset",(pageNum-1)*pageSize);
        map.put("count",pageSize);
        return chapter01Mapper.findAll(map);
    }
  1. Mapper介面
public interface Chapter01Mapper {
    List<UserEntity> findAll(HashMap<String,Integer> map);
}
  1. Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.Mapper.Chapter01Mapper">
    <resultMap id="UserResultMap" type="com.example.Chapter01.UserEntity">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="phone" column="phone"/>
        <result property="address" column="address"/>
    </resultMap>

    <sql id="baseSQL">
        select * from `table`
    </sql>
    <!-- 手動配置分頁 -->
    <select id="findAll" parameterType="HashMap" resultMap="UserResultMap">
        <include refid="baseSQL"/>
        <if test="offset != null and count != null">
         limit #{offset},#{count}
        </if>
    </select>
</mapper>

使用PageHelper

  1. 匯入依賴
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.6</version>
</dependency>
  1. controller
    //PageHelper外掛方法
    @GetMapping("/chapter01/pageHelper")
    public PageInfo<UserEntity> chapter02(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize){
        PageHelper.startPage(pageNum,pageSize);
        List<UserEntity> list =chapter01Mapper.findAllByPage();
        return new PageInfo<>(list);
    }
  1. mapper介面
public interface Chapter01Mapper {
    List<UserEntity> findAllByPage();
}
  1. mapper.xml
    <!-- 省略 -->
    <!-- PageHelper分頁 -->
    <select id="findAllByPage" resultMap="UserResultMap">
        <include refid="baseSQL"/>
    </select>

在使用PageHelper進行分頁時,PageHelper.startPage(pageNum,pageSize)是開啟分頁功能的關鍵程式碼,透過傳入當前頁碼和頁面記錄顯示數即可自動計算分頁相關的屬性,並將計算出的所有資料封裝在Page物件內,Page繼承自ArrayList,所以後續不僅可以得到查詢列表還可以透過呼叫Page的暴露方法得到Page內部與分頁相關的資料,比如頁碼、頁面大小、起始行、末行、總數、總頁數、排序等。但實際上想要一次性返回所有關鍵性資訊可以使用PageInfo物件,PageInfo包含的分頁資訊比Page更全,對於前端來說返回的資料更加完整規範,在例子中使用PageInfo的構造方法傳入page物件將page轉換為PageInfo返回,也可透過Page的toPageInfo方法直接轉換。

小結

除錯的時候發現在執行List<UserEntity> list =chapter01Mapper.findAllByPage();後,本應返回的List型別實際上被修改為Page。看了下原始碼和查閱資料得到一些粗糙簡單的結論:

  • 在MyBatis整合PageHelper的情況下,當呼叫chapter01Mapper.findAllByPage()方法時,PageHelper會在該方法執行前攔截並進行一些處理,其中之一就是開啟分頁,PageHelper透過AOP(面向切面程式設計)的方式,在findAllByPage()方法執行前動態地修改其行為,比如SQL語句後新增分頁語句,以實現分頁功能,並將結果封裝成一個Page物件。

相關文章