`
aimer311
  • 浏览: 94896 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

ibatis处理sybase分页的问题(还没有解决)续

    博客分类:
  • java
阅读更多
[size=medium]  承接上一篇,以下是早上探讨的内容,纯粹是兴趣。
搜索了下hibernate的分页原理,我还没用过hibernate。有篇文章说hibernate的分页有3中机制,首先是根据不同的数据库组装具体数据库的分页sql,如mysql的getLimitString(),若数据库不支持那么使用游标定位,再不行,使用rs.next()一条一条定位。这个过程是很好理解的。所以我也看看ibatis是否是这么实现了的。当然第一种方式我在上一篇文章已经对于一般的数据库可以很好的实现了。
跟踪到com.ibatis.sqlmap.engine.execution.SqlExecutor.class.代码如下:
  private void handleResults(StatementScope statementScope, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException {
    try {
      statementScope.setResultSet(rs);
      ResultMap resultMap = statementScope.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(statementScope, rs).getResults(statementScope, rs);
          callback.handleResultObject(statementScope, columnValues, rs);
          resultsFetched++;
        }
      }
    } finally {
      statementScope.setResultSet(null);
    }
  }

可以看到确实是按照两种方式进行定位的,如果ResultSet的type是TYPE_FORWARD_ONLY那么采用的是游标一条一条定位,否则是absolute(int).一方面是这两种方式有差别吗?另一方面是我怎么让ibatis采用absolute定位。毕竟想当然觉得这个比较快。
我用200w+条数据测试了下,这两种方法差别不大,在200ms内。absolute确实快一点点,具体为什么可以查看其实现方式,不深入了。在做这个测试的时候就出现了outOfMemory问题,所以应该是强烈不建议用这个来分页,虽然你可能说你的内存有多大多大的。而且时间上也是一个问题。那么,怎么让ibatis使用absolute定位呢?有些数据库驱动是不支持absolute,last定位的,当然现在大部分是支持的,我们用的jconn3.jar是支持的。看看上面的代码,主要在这一句:
Integer rsType = statementScope.getStatement().getResultSetType();

看看ibatis是如何创建statementScope对象的
StatementScope statementScope = beginStatementScope(sessionScope, ms);

此时返回的statement中的ResultSetType是null,以后也并没有对其进行修改过,当然我们可以很容易的重写handleResults方法,或者在哪里对其ResultSet的Type进行赋值,但是这带来以后维护的问题。我在想是否可以在哪里配置这个呢?还有hibernate是否也一样的呢?即返回的ResultSet type都是ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY的?[/size]
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics