ibatisページングソース分析


ibatisではqueryForPaginatedList(java.lang.String id,int pageSize)が魅力的で、PaginatedListのオブジェクトを返すことができます.
ページをめくることを実現して、さっきPaginatedListをテストして、1-2 w行のデータの時にまた仕事をすることができて、しかし1つの30 w行の表の中でページをめくって、一回selectは363.031 secondを使いました
思わずソースを見てみるとibatisのページングはデータベースのjdbcDriver.に依存していることがわかりました.
呼び出し順序は以下の通りである.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)をサポートするかどうかを見ることができる.
このような実装は、データベースが自分でサポートしているページング方式ほど速くはありません.データ量の大きいテーブルにぶつかると、すぐに死んでしまいます.