La paginación de PageHelper falla, solo se puede encontrar la primera página
1. fenómeno
-
El código de paginación es el siguiente:
int pageId = Constants.ONE; boolean isHasNextPage; do { PageHelper.startPage(pageId, Constants.DEFAULT_PAGE_SIZE); List<String> projectIdList = marketingConsStageDAO.getAllProjectId(); PageInfo<String> pageInfo = new PageInfo<>(projectIdList); // 此处省略业务逻辑 isHasNextPage = pageInfo.isHasNextPage(); pageId++; } while (isHasNextPage);
-
marketingConsStageDAO.getAllProjectId()
El código se muestra a continuación:public List<String> getAllProjectId() { Weekend<MarketingConsStage> weekend = Weekend.of(MarketingConsStage.class, true, true); weekend.selectProperties("projectId"); weekend.setDistinct(true); return marketingConsStageMapper.selectByExample(weekend) .stream() .map(MarketingConsStage::getProjectId) .collect(Collectors.toList()); }
-
marketingConsStageDAO.getAllProjectId()
Debería devolver más de 20.000 datos, por lo que se espera quedo-while
el bucle se ejecute muchas veces, pero se encuentra la primera páginaisHasNextPage
y el buclefalse
no se puede continuar ;do-while
2. Razón
-
Continúe
debug
y alcance el punto de interrupción enPageInfo<String> pageInfo = new PageInfo<>(projectIdList);
Esta línea, y luego descubrió que el tipo de retorno
projectIdList
esArrayList
; -
Eche un vistazo al
PageInfo
método de construcción:/** * 包装Page对象 * * @param list page结果 * @param navigatePages 页码数量 */ public PageInfo(List<T> 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(); //由于结果是>startRow的,所以实际的需要+1 if (this.size == 0) { this.startRow = 0; this.endRow = 0; } else { this.startRow = page.getStartRow() + 1; //计算实际的endRow(最后一页的时候特殊) 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) { calcByNavigatePages(navigatePages); } }
-
Se puede ver que debido a que
projectIdList
esArrayList
un tipo, cuando se crea el objeto , la lógica delpageInfo
número total de páginas va directamente , lo que resulta en una falla de paginación;this.pages = this.pageSize > 0 ? 1 : 0;
-
si lo haremos
.stream() .map(MarketingConsStage::getProjectId) .collect(Collectors.toList());
La operación se coloca fuera de la operación de consulta de paginación y el código se modifica para:
int pageId = Constants.ONE; boolean isHasNextPage; do { PageHelper.startPage(pageId, Constants.DEFAULT_PAGE_SIZE); List<MarketingConsStage> marketingConsStageList = marketingConsStageDAO.getAllProjectId(); PageInfo<MarketingConsStage> pageInfo = new PageInfo<>(marketingConsStageList); List<String> projectIdList = marketingConsStageList.stream() .map(MarketingConsStage::getProjectId) .collect(Collectors.toList()); // 此处省略业务逻辑 isHasNextPage = pageInfo.isHasNextPage(); pageId++; } while (isHasNextPage);
se
marketingConsStageDAO.getAllProjectId()
modificará a:public List<MarketingConsStage> getAllProjectId() { Weekend<MarketingConsStage> weekend = Weekend.of(MarketingConsStage.class, true, true); weekend.selectProperties("projectId"); weekend.setDistinct(true); return marketingConsStageMapper.selectByExample(weekend); }
Luego
debug
encontrará quemarketingConsStageList
es unaPage
variable de tipo y que la función de paginación es normal en este momento;
3. Principio de funcionamiento de PageHelper
PageHelper
Es unMyBatis
complemento de paginación que puede ayudarnos a realizar el procesamiento de paginación al consultar datos. Cuando llamamosPageHelper.startPage(pageNum, pageSize)
al método, se usará en la parte inferior para guardar los parámetros de paginación del hilo actual y luego reescribirá la declaraciónThreadLocal
a través del interceptor para realizar la consulta de paginación.SQL
- Después de llamar
PageHelper.startPage(pageNum, pageSize)
al método, la declaración de consulta ejecutada inmediatamenteSQL
seráPageHelper
interceptada y reescrita, de modo que solo se devolverán los datos del número especificado de páginas y el número de registros por página al consultar los resultados.PageHelper
El resultado de la consulta se encapsulará en unPage
objeto, quePage
contiene el número total de registros del resultado de la consulta, el número de página actual, el número de registros por página y la lista de datos del resultado de la consulta. - Por lo tanto, cuando llamamos al método de consulta, el objeto devuelto
list
se puedePageHelper
encapsular enPage
un objeto. Esto se debe a quePageHelper
el resultado de la consulta se encapsula en la capa inferior y el resultado de la consulta sePage
devuelve a la persona que llama en forma de objeto. La persona que llama puedePage
obtener diversa información del resultado de la consulta a través del objeto, como el número total de registros, el número de páginas actuales, el número de registros por página, etc., y también puede obtener la lista de datos del resultado de la consulta a través del objetoPage
. el objeto. - En resumen,
PageHelper
el proceso de implementación de la consulta de paginación se puede resumir como: habilitar la consulta de paginación -> ejecutar la operación de consulta -> devolver la lista de resultados de la consulta a la persona que llama y envolverla en forma de objeto -> la persona que llama obtiene diversa informaciónPage
dePage
paginación Consulta a través del objeto.