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

调用次序如下SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList

->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList

->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback

->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults()

iBATIS分页处理的函数如下


  1. privatevoidhandleResults(RequestScope request, ResultSet rs,intskipResults,intmaxResults, RowHandlerCallback callback)throws
  2. try
  3. request.setResultSet(rs);
  4. ResultMap resultMap = request.getResultMap();
  5. if(resultMap !=null) {
  6. // Skip Results
  7. if
  8. if(skipResults > 0) {


  9. rs.absolute(skipResults);
  10. }
  11. else
  12. for(inti = 0; i < skipResults; i++) {
  13. if
  14. return;
  15. }
  16. }
  17. }


  18. // Get Results
  19. intresultsFetched = 0;
  20. while
  21. Object[] columnValues = resultMap.resolveSubMap(request, rs).getResults(request, rs);
  22. callback.handleResultObject(request, columnValues, rs);
  23. resultsFetched++;
  24. }
  25. }
  26. finally
  27. null);
  28. }
  29. }


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


  1. privateList getList(intidx,intlocalPageSize)throws
  2. return
  3. }


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

这种实现肯定不如数据库自己支持的分页方式来的快,一旦碰到数据量大的表,有停滞的可能。