美文网首页
Mybatis逻辑分页原理解析RowBounds

Mybatis逻辑分页原理解析RowBounds

作者: hero_2be8 | 来源:发表于2019-07-14 21:56 被阅读0次

背景:某个场景是需要进行列表的分页展示;采用的方案是通过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();

      }

    }

  }

相关文章

网友评论

      本文标题:Mybatis逻辑分页原理解析RowBounds

      本文链接:https://www.haomeiwen.com/subject/qqtwkctx.html