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

JDBC 離線資料集 RowSet 入門:解決分頁與連線管理難題

     編輯:Java 相關知識

直接使用 JDBC API 開發時,最常用的是 ResultSet 介面讀取資料。但 ResultSet 屬於線上資料集,讀取過程中必須維持資料庫連線,僅能在讀取完畢後關閉相關資源,使用上不夠靈活。Java 標準庫其實提供了離線資料集方案——javax.sql.RowSet 介面及其子介面,Sun JDK 內建預設實作,Oracle 等大型資料庫驅動也提供專屬實作。本文以 Sun 預設實作 CachedRowSetImpl 為例,搭配 SQL Server 2000 Northwind 資料庫,示範離線資料集的基本操作與分頁查詢技巧。

一、核心概念:RowSet vs ResultSet

特性ResultSet (線上)RowSet (離線)
連線狀態讀取期間必須保持連線資料填充後可立即關閉連線
序列化不支援支援,可跨網路傳輸
捲動/更新視驅動支援度而定標準化支援捲動、更新、分頁
適用場景即時大量資料串流處理分頁顯示、資料傳遞、離線操作

二、基本查詢:CachedRowSetImpl 完整範例

import java.sql.*;
import javax.sql.RowSet;
import com.sun.rowset.CachedRowSetImpl;

public class RowSetDemo {
    public static RowSet query(Connection conn, String sql) throws SQLException {
        CachedRowSetImpl rowset = new CachedRowSetImpl();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        rowset.populate(rs);  // 將線上 ResultSet 資料填充至離線 RowSet
        rs.close();
        stmt.close();
        return rowset;        // 此時可安全關閉連線
    }

    public static void main(String[] args) throws Exception {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        String url = "jdbc:sqlserver://127.0.0.1:1433;database=Northwind;user=sa;password=huhuiyu";
        Connection conn = DriverManager.getConnection(url);
        RowSet rs = query(conn, "SELECT * FROM Customers ORDER BY CustomerID");
        conn.close();  // 連線關閉後仍可操作 RowSet

        while (rs.next()) {
            System.out.print(rs.getString(1) + " : ");
            System.out.println(rs.getString("CompanyName"));
        }
    }
}

關鍵步驟:

  1. 建立 CachedRowSetImpl 實例
  2. 執行查詢取得 ResultSet
  3. 呼叫 populate(rs) 將資料複製到離線集合
  4. 立即關閉 ResultSet、Statement 與 Connection
  5. 後續像操作 ResultSet 一樣使用 RowSet(next()、getString() 等)

三、進階應用:內建分頁查詢功能

CachedRowSetImpl 原生支援分頁,無需手工計算 LIMIT/OFFSET 或使用子查詢:

public static RowSet query(Connection conn, String sql, int pageSize, int pageNumber) throws SQLException {
    CachedRowSetImpl rowset = new CachedRowSetImpl();
    // 必須使用可捲動的 ResultSet
    Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    ResultSet rs = stmt.executeQuery(sql);
    
    rowset.setPageSize(pageSize);                    // 設定每頁筆數
    int skip = (pageNumber - 1) * pageSize + 1;      // 計算起始游標位置(1-based)
    rowset.populate(rs, skip);                       // 從指定位置填充
    
    rs.close();
    stmt.close();
    return rowset;
}

// 使用範例:查詢第 2 頁,每頁 5 筆
RowSet rs = query(conn, "SELECT * FROM Customers ORDER BY CustomerID", 5, 2);

原理:populate(rs, startRow) 會從 ResultSet 的第 startRow 列開始讀取 pageSize 筆資料。搭配 TYPE_SCROLL_SENSITIVE 確保游標可定位。

四、實務建議與注意事項

  • 套件相依性:com.sun.rowset.CachedRowSetImpl 屬 Sun 內部實作,跨 JDK 版本可能變動;生產環境建議使用標準 javax.sql.rowset.RowSetFactory (JDBC 4.1+) 或資料庫廠商提供的實作(如 Oracle oracle.jdbc.rowset.OracleCachedRowSet)
  • 資料量考量:離線資料集將所有資料載入記憶體,不適用於超大結果集;大數據量場景仍建議使用游標式分頁或資料庫原生分頁
  • 更新回寫:RowSet 支援 updateRow()、insertRow()、deleteRow() 等離線修改,稍後可透過 acceptChanges() 批次回寫資料庫,需處理並發衝突
  • 序列化傳遞:RowSet 實作 Serializable,可直接在分層架構間傳遞(如 EJB 遠端介面、Web Service),避免手工轉換 DTO

五、結語

若專案未引入持久層框架(Hibernate、MyBatis 等),善用 JDBC 內建的 RowSet 離線資料集,能優雅解決分頁查詢、連線池釋放、跨層資料傳遞等常見痛點。掌握 CachedRowSetImpl 的基本操作與分頁技巧,是 Java 開發者進階 JDBC 應用的關鍵技能之一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved