天天看点

iBatis分页源代码解析

在ibatis中有一个很吸引人的方法,queryForPaginatedList(java.lang.String id, int pageSize),可以返回 PaginatedList的对象,实现翻页,刚才测试了一下PaginatedList,在1-2w行数据的时候还可以工作,但是在一个30w行的表里翻页,一次select用了363.031second .忍不住看了一下源,发现ibatis的分页依赖于数据库的jdbcDriver.

调用次序如下

SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults()

分页处理的函数如下

iBatis分页源代码解析
iBatis分页源代码解析

private   void  handleResults(RequestScope request, ResultSet rs,  int  skipResults,  int  maxResults, RowHandlerCallback callback)  throws  SQLException  ... {

iBatis分页源代码解析
iBatis分页源代码解析

    try ...{

iBatis分页源代码解析

      request.setResultSet(rs);

iBatis分页源代码解析

      ResultMap resultMap = request.getResultMap();

iBatis分页源代码解析
iBatis分页源代码解析

      if (resultMap != null) ...{

iBatis分页源代码解析

        // Skip Results

iBatis分页源代码解析
iBatis分页源代码解析

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

iBatis分页源代码解析
iBatis分页源代码解析

          if (skipResults > 0) ...{ 

iBatis分页源代码解析

            rs.absolute(skipResults);

iBatis分页源代码解析

          }

iBatis分页源代码解析
iBatis分页源代码解析

        } else ...{

iBatis分页源代码解析
iBatis分页源代码解析

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

iBatis分页源代码解析
iBatis分页源代码解析

            if (!rs.next()) ...{

iBatis分页源代码解析

              return;

iBatis分页源代码解析

            }

iBatis分页源代码解析

          }

iBatis分页源代码解析

        } 

iBatis分页源代码解析
iBatis分页源代码解析

        // Get Results

iBatis分页源代码解析

        int resultsFetched = 0;

iBatis分页源代码解析
iBatis分页源代码解析

        while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults) && rs.next()) ...{

iBatis分页源代码解析

          Object[] columnValues = resultMap.resolveSubMap(request, rs).getResults(request, rs);

iBatis分页源代码解析

          callback.handleResultObject(request, columnValues, rs);

iBatis分页源代码解析

          resultsFetched++;

iBatis分页源代码解析

        }

iBatis分页源代码解析

      }

iBatis分页源代码解析
iBatis分页源代码解析

    } finally ...{

iBatis分页源代码解析

      request.setResultSet(null);

iBatis分页源代码解析

    }

iBatis分页源代码解析

  }  返回的PaginatedList实际上是PaginatedDataList类的对象,每次翻页的时候最后都会调用

iBatis分页源代码解析
iBatis分页源代码解析

  private  List getList( int  idx,  int  localPageSize)  throws  SQLException  ... { 

iBatis分页源代码解析

    return sqlMapExecutor.queryForList(statementName, parameterObject, (idx) * pageSize, localPageSize);

iBatis分页源代码解析

  } 这个方法,可见ibatis的分页机制要看jdbcDriver如何实现以及是否支持rs.absolute(skipResults)。

这种实现肯定不如数据库自己支持的分页方式来的快,一旦碰到数据量大的表,马上会死翘翘。