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<Object> resultContext = new DefaultResultContext<Object>();

  //跳过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();

      }

    }

  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容