首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

[JAVA100例] 第55例:JDBC 可滾動結果集——分頁查詢實戰

     編輯:Java 相關知識

本例演示使用可滾動結果集 (ResultSet.TYPE_SCROLL_INSENSITIVE) 實現高效分頁查詢:移動游標到指定頁首行,僅讀取當前頁數據,避免全量加載。

核心代碼

public class JDBCScrollConn {
  private static String url, username, password;

  public Connection conn() { ... }  // 同前例

  // 簡單查詢
  public void query(Connection con, String sql) { ... }

  // 分頁查詢核心
  public void query(Connection con, String sql, int pageNo, int pageSize) {
    try {
      if (con == null) throw new Exception("database connection can't use!");
      if (sql == null) throw new Exception("check your parameter: 'sql'! don't input null!");

      // 1. 創建可滾動只讀 Statement
      Statement stmt = con.createStatement(
        ResultSet.TYPE_SCROLL_INSENSITIVE,  // 可滾動,不感知數據變化
        ResultSet.CONCUR_READ_ONLY          // 只讀
      );
      ResultSet rs = stmt.executeQuery(sql);
      ResultSetMetaData rmeta = rs.getMetaData();
      int numColumns = rmeta.getColumnCount();

      // 2. 獲取總記錄數(移動到最後一行)
      rs.last();
      int intRowCount = rs.getRow();
      int intPageCount = (intRowCount + pageSize - 1) / pageSize;

      // 3. 邊界校正
      if (pageNo > intPageCount) pageNo = intPageCount;

      // 4. 定位到頁首行並讀取
      if (intPageCount > 0) {
        rs.absolute((pageNo - 1) * pageSize + 1);  // 絕對定位
        int i = 0;
        while (i < pageSize && !rs.isAfterLast()) {
          for (int j = 0; j < numColumns; j++)
            System.out.print(rs.getString(j+1) + " ");
          i++; rs.next(); System.out.println();
        }
      }
    } catch (Exception e) { System.out.println("query error:" + e); }
  }

  public void demo(int pageNo, int pageSize) { ... }
  public static void main(String[] arg) { ... }
}

ResultSet 類型與併發性

常量說明
TYPE_FORWARD_ONLY默認,僅能 next() 向前,不可滾動
TYPE_SCROLL_INSENSITIVE可滾動,結果集快照,不見他人提交的修改
TYPE_SCROLL_SENSITIVE可滾動,實時見他人提交的修改(性能較差)
CONCUR_READ_ONLY只讀,不可更新
CONCUR_UPDATABLE可更新,支持 updateRow()/deleteRow()/insertRow()

關鍵游標操作方法

方法作用
absolute(int row)移動到指定行號(1-based,負數從後向前)
relative(int rows)相對當前位置移動
first()/last()移動到首/尾行
beforeFirst()/afterLast()移動到首行前/尾行後
getRow()獲取當前行號(1-based)
isFirst()/isLast()/isBeforeFirst()/isAfterLast()位置判斷

性能與局限性分析

  • 優勢:避免應用層全量緩存,內存佔用穩定
  • 劣勢:rs.last() 驅動可能需遍歷全表獲取行數;游標佔用數據庫資源;長事務風險
  • 數據庫支持差異:Oracle/PostgreSQL/MySQL 支持度不同,MySQL 需配合 useCursorFetch=true

現代分頁最佳實踐

  1. SQL 級分頁:LIMIT offset, size (MySQL/PostgreSQL)、OFFSET ... FETCH NEXT (Oracle 12c+、SQL Server 2012+)
  2. 游標/Keyset 分頁:WHERE id > lastId ORDER BY id LIMIT size,深分頁性能優越
  3. 框架整合:MyBatis RowBounds、PageHelper、Spring Data Pageable
  4. 計數優化:緩存總數、估算行數、異步計數
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved