在ibatis中有一個(gè)很吸引人的方法,queryForPaginatedList(java.lang.String id, int pageSize),可以返回 PaginatedList的對(duì)象,
實(shí)現(xiàn)翻頁(yè),剛才測(cè)試了一下PaginatedList,在1-2w行數(shù)據(jù)的時(shí)候還可以工作,但是在一個(gè)30w行的表里翻頁(yè),一次select用了363.031second
忍不住看了一下源,發(fā)現(xiàn)ibatis的分頁(yè)依賴于數(shù)據(jù)庫(kù)的jdbcDriver.
調(diào)用次序如下SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList
->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList
->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback
->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults()
分頁(yè)處理的函數(shù)如下
- 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) {
-
-
-
- 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;
-
- }
-
- }
-
- }
-
-
- 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);
- }
- }
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 Resultsif (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 Resultsint 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實(shí)際上是PaginatedDataList類的對(duì)象,每次翻頁(yè)的時(shí)候最后都會(huì)調(diào)用
- private List getList(int idx, int localPageSize) throws SQLException {
-
- return sqlMapExecutor.queryForList(statementName, parameterObject, (idx) * pageSize, localPageSize);
-
- }
private List getList(int idx, int localPageSize) throws SQLException {return sqlMapExecutor.queryForList(statementName, parameterObject, (idx) * pageSize, localPageSize);}
這個(gè)方法,可見(jiàn)ibatis的分頁(yè)機(jī)制要看jdbcDriver如何實(shí)現(xiàn)以及是否支持rs.absolute(skipResults)。
這種實(shí)現(xiàn)肯定不如數(shù)據(jù)庫(kù)自己支持的分頁(yè)方式來(lái)的快,一旦碰到數(shù)據(jù)量大的表,馬上會(huì)死翹翹。