PageHelper pagination fails, only the first page can be found

PageHelper pagination fails, only the first page can be found

1. phenomenon

  1. The pagination code is as follows:

    		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);
    
  2. marketingConsStageDAO.getAllProjectId()code show as below:

    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());
    	}
    
  3. marketingConsStageDAO.getAllProjectId()It should return more than 20,000 pieces of data, so it is expected that do-whilethe loop will be executed many times, but the first page is found isHasNextPage, and the loop falsecannot be continued ;do-while

2. Reason

  1. Go ahead debugand hit the breakpoint at

    PageInfo<String> pageInfo = new PageInfo<>(projectIdList);
    

    This line, and then found that the return type projectIdListis ArrayList;insert image description here

  2. Take a look at PageInfothe construction method:

    		/**
         * 包装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);
            }
        }
    
  3. It can be seen that because projectIdListit is ArrayLista type, when the object is created , the logic of pageInfothe total number of pages goes directly , resulting in paging failure;this.pages = this.pageSize > 0 ? 1 : 0;

  4. if we will

    .stream()
    .map(MarketingConsStage::getProjectId)
    .collect(Collectors.toList());
    

    The operation is placed outside the paging query operation, and the code is modified to:

    		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);
    

    will be marketingConsStageDAO.getAllProjectId()modified to:

    public List<MarketingConsStage> getAllProjectId() {
          
          
    
    		Weekend<MarketingConsStage> weekend = Weekend.of(MarketingConsStage.class, true, true);
    		weekend.selectProperties("projectId");
    		weekend.setDistinct(true);
    
    		return marketingConsStageMapper.selectByExample(weekend);
    	}
    

    Then debugyou will find that marketingConsStageListit is a Pagetype variable, and the paging function is normal at this time;insert image description here

3. Working principle of PageHelper

  1. PageHelperIt is a MyBatispagination plug-in, which can help us perform paging processing when querying data. When we call PageHelper.startPage(pageNum, pageSize)the method, it will be used at the bottom to save the paging parameters of the current thread, and then rewrite the statement ThreadLocalthrough the interceptor to realize paging query.SQL
  2. After we call PageHelper.startPage(pageNum, pageSize)the method, the query statement executed immediately SQLwill be PageHelperintercepted and rewritten, so that only the data of the specified number of pages and the number of records per page will be returned when querying the results. PageHelperThe query result will be encapsulated into an Pageobject, which Pagecontains the total number of records of the query result, the current page number, the number of records per page, and the data list of the query result.
  3. Therefore, when we call the query method, the returned object listcan be PageHelperwrapped into Pagean object. This is because PageHelperthe query result is encapsulated at the bottom layer, and the query result is Pagereturned to the caller in the form of an object. The caller can Pageobtain various information of the query result through the object, such as the total number of records, the number of current pages, the number of records per page, etc., and can also Pageobtain the data list of the query result through the object.
  4. In short, PageHelperthe process of implementing pagination query can be summarized as: enable paging query -> execute query operation -> return the query result list to the caller, and wrap it in the form of object - Page> the caller Pageobtains various information of paging query through the object .

Guess you like

Origin blog.csdn.net/itigoitie/article/details/131812918