Backend Development 7 min read

Fixing Incorrect Total Count in PageHelper Pagination Using PageInfo

This article analyzes why the total record count returned by PageHelper mismatches the actual number of rows, examines the underlying PageInfo and PageSerializable source code, and provides a concrete solution that avoids type conversion and directly constructs PageInfo from the mapper result to ensure accurate pagination.

JD Tech
JD Tech
JD Tech
Fixing Incorrect Total Count in PageHelper Pagination Using PageInfo

The article discusses an issue encountered when using the PageHelper pagination plugin where the returned total value incorrectly matches the pageSize instead of the actual total number of records. It first outlines the problem description, showing that the database count exceeds the returned total and presenting the relevant screenshot.

Problem Analysis

By inspecting the source code of PageInfo<T> , it is observed that the constructor does not handle the total field when the supplied list is not an instance of Page . The parent class PageSerializable sets total to list.size() in such cases, which explains the discrepancy when the mapper's result list is wrapped into a different object.

public class PageInfo
extends PageSerializable
{
    /**
     * 包装Page对象
     * @param list          page结果
     * @param navigatePages 页码数量
     */
    public PageInfo(List
list, int navigatePages) {
        super(list);
        if (list instanceof Page) {
            Page page = (Page) list;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();
            this.pages = page.getPages();
            this.size = page.size();
            if (this.size == 0) {
                this.startRow = 0;
                this.endRow = 0;
            } else {
                this.startRow = page.getStartRow() + 1;
                this.endRow = this.startRow - 1 + this.size;
            }
        } else if (list instanceof Collection) {
            this.pageNum = 1;
            this.pageSize = list.size();
            this.pages = this.pageSize > 0 ? 1 : 0;
            this.size = list.size();
            this.startRow = 0;
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;
        }
        if (list instanceof Collection) {
            this.navigatePages = navigatePages;
            calcNavigatepageNums();
            calcPage();
            judgePageBoudary();
        }
    }
}

The parent class implementation:

public PageSerializable(List
list) {
    this.list = list;
    if (list instanceof Page) {
        this.total = ((Page) list).getTotal();
    } else {
        this.total = list.size();
    }
}

Debugging confirms that the mapper returns a Page instance, but the code later replaces it with another object, causing total to be set to the list size.

Solution

To avoid the loss of the correct total count, construct PageInfo directly from the mapper's return value without any type conversion or re‑wrapping:

// Correct usage example
PageInfo
pageInfo = new PageInfo<>(mapperMethod(params));

Best Practice

When using PageInfo , always pass the original Page object returned by MyBatis mapper to the constructor; do not transform the list into another collection or custom wrapper, as this will cause the total field to be incorrectly calculated.

backenddebuggingJavaMyBatispaginationPageHelperPageInfo
JD Tech
Written by

JD Tech

Official JD technology sharing platform. All the cutting‑edge JD tech, innovative insights, and open‑source solutions you’re looking for, all in one place.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.