Mybatis逻辑分页原理解析RowBounds

背景:某个场景是需要进行列表的分页展示;采用的方案是通过mybatis的逻辑分页RowBounds实现,其中limit的值是20,offset取的是(page-1)乖以limit;当page为1时得到的数据是正常的,但是当page大于1时得到的数据偏移量确是从page乘以200后开始的,和实际想得到的数据完全不匹配;

原因分析:mybatis逻辑分页的实现原理是先取出所有符合查询条件的数据,然后舍弃掉前面offset条的数据,再从剩下的数据中取出limit条;

private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler resultHandler, RowBounds rowBounds, ResultMapping parentMapping)

      throws SQLException {

    DefaultResultContext resultContext = new DefaultResultContext();

  //跳过RowBounds设置的offset值

    skipRows(rsw.getResultSet(), rowBounds);

  //判断数据是否小于limit,如果小于limit的话就不断的循环取值

    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {

      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);

      Object rowValue = getRowValue(rsw, discriminatedResultMap);

      storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());

    }

  }

private boolean shouldProcessMoreRows(ResultContext context, RowBounds rowBounds) throws SQLException {

   //判断数据是否小于limit,小于返回true

    return !context.isStopped() && context.getResultCount() < rowBounds.getLimit();

  }

  //跳过不需要的行,应该就是rowbounds设置的limit和offset

  private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {

    if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {

      if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {

        rs.absolute(rowBounds.getOffset());

      }

    } else {

   //跳过RowBounds中设置的offset条数据

      for (int i = 0; i < rowBounds.getOffset(); i++) {

        rs.next();

      }

    }

  }
 

                            
                        
                    
                    
                    

你可能感兴趣的:(Mybatis逻辑分页原理解析RowBounds)