论坛首页 Java企业应用论坛

ibatis分页源码分析

浏览 36309 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-08-25  
在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()
分页处理的函数如下
private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback); throws SQLException {
    try {
      request.setResultSet(rs);;
      ResultMap resultMap = request.getResultMap();;
      if (resultMap != null); {
        // Skip Results
        if (rs.getType(); != ResultSet.TYPE_FORWARD_ONLY); {
          if (skipResults > 0); {
            rs.absolute(skipResults);;
          }
        } else {
          for (int i = 0; i < skipResults; i++); {
            if (!rs.next();); {
              return;
            }
          }
        }

        // Get Results
        int resultsFetched = 0;
        while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults); && rs.next();); {
          Object[] columnValues = resultMap.resolveSubMap(request, rs);.getResults(request, rs);;
          callback.handleResultObject(request, columnValues, rs);;
          resultsFetched++;
        }
      }
    } finally {
      request.setResultSet(null);;
    }
  }

返回的PaginatedList实际上是PaginatedDataList类的对象,每次翻页的时候最后都会调用
 private List getList(int idx, int localPageSize); throws SQLException {
    return sqlMapExecutor.queryForList(statementName, parameterObject, (idx); * pageSize, localPageSize);;
  }

这个方法,可见ibatis的分页机制要看jdbcDriver如何实现以及是否支持rs.absolute(skipResults)。
这种实现肯定不如数据库自己支持的分页方式来的快,一旦碰到数据量大的表,马上会死翘翘。
   发表时间:2006-08-28  
是呀。。同意你的观点,其实,我一直觉得物理翻页是最好的,ibatis不支持物理翻页,这点比较费解。我想把物理翻页封装起来,但感觉不是特别好做。坛子里搞ibatis的人好象不是很多呀。。看来,这个项目也不是特别活跃。
0 请登录后投票
   发表时间:2006-09-13  
SqlMapClientImpl , SqlMapSessionImpl有什么不同???郁闷中
0 请登录后投票
   发表时间:2006-09-13  
分页工具,最好还是自己封装成类!
Ibatis这个还不能满足大多数应用!
比如,数字分页,上下分页,跳转等等!
不可能将这些代码重复得写!
且分页让SQL控制,是较好的性能表现!
mysql:
select * from A limit startRow,endRow
oracle:
select b.* from (select a.*,rownum as linenum from (select * from A) a where rownum <= endRow) b where linenum >= startRow
0 请登录后投票
   发表时间:2006-09-13  
而且这个东西要写order by的  否则翻一翻数据就会乱掉
0 请登录后投票
   发表时间:2006-09-13  
总之不要用,除非你的数据量很小
0 请登录后投票
   发表时间:2006-09-13  
直接用SQL实现可以了,针对不同数据库的都有,GOOGLE一下?
0 请登录后投票
   发表时间:2006-09-14  
Ibatis不是物理分页,不要用queryForPaginatedList,性能不好。他也没有针对各种数据库做实现。这个自己实现就好了,很简单的事情
0 请登录后投票
   发表时间:2006-09-18  
LZ的性能问题主要是因为你的数据库不支持ResultSet的absolute方法吧?若支持这个方法这个性能问题应该不存在的。

引用
          for (int i = 0; i < skipResults; i++) {
            if (!rs.next()) {
              return;
            }
          }


应该是这部分代码是性能瓶颈。

queryForPaginatedList()方法其实很好用,足够实现所有的分页功能,包括跳转、页面单击排序、页面指定容量等特性,只需加一个包装类即可,使用数据库的分页功能,虽然性能最好,但要实现完善的分页特性,包装类也要花大量的时间编写和测试的。

除去旧版本的数据库,目前的jdbc Driver极少不支持ResultSet的absolute方法,我做过的一个项目是MySql4.1,10W数据测试,分页速度很快,绝对没有360秒级的恐怖问题。
0 请登录后投票
   发表时间:2006-09-18  
孤立数据库谈ibatis的翻页问题是不完善的,至少要对这三个数据库进行测试mysql,postgresql,oracle,同时还要确定版本。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics