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

JDBC ResultSet 完全指南:四大類型、滾動/更新/保持特性、核心 API 與最佳實踐

     編輯:Java 綜合教學

JDBC ResultSet 完全指南:四大類型、滾動/更新/保持特性、核心 API 與最佳實踐

ResultSet 封裝 SQL 查詢結果,不僅是數據容器,更提供游標導航、數據更新、事務保持等豐富功能。本文系統梳理 JDBC 2.0/3.0 規範下的 ResultSet 分類、創建參數、核心方法與實戰模式。

一、ResultSet 四大類型對比

類型創建參數游標移動可更新提交後保持適用場景
TYPE_FORWARD_ONLY無參 createStatement()僅 next() 向前否否(默認關閉)單次順序讀取、大數據流
TYPE_SCROLL_INSENSITIVEcreateStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)任意向前/向後/定位否視 HOLD 參數需隨機訪問、不關心並發修改
TYPE_SCROLL_SENSITIVEcreateStatement(TYPE_SCROLL_SENSITIVE, CONCUR_READ_ONLY)任意移動否視 HOLD 參數需實時看到他事務提交的修改
CONCUR_UPDATABLEcreateStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE)任意移動是視 HOLD 參數需通過 ResultSet 修改數據庫

JDBC 3.0 新增:第三參數 HOLD_CURSORS_OVER_COMMIT / CLOSE_CURSORS_AT_COMMIT 控制提交後游標是否保持打開。

二、創建可滾動/可更新 ResultSet

// 僅可滾動,只讀
Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_READ_ONLY);

// 可滾動 + 可更新
Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_UPDATABLE);

// JDBC 3.0 完整參數
Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_UPDATABLE,
    ResultSet.HOLD_CURSORS_OVER_COMMIT);

三、可更新 ResultSet 前提條件

SQL 必須滿足:

  1. 單表查詢(無 JOIN)。
  2. 無 GROUP BY、HAVING、聚合函數。
  3. 選列包含主鍵或唯一索引列(用於定位行)。

四、核心導航方法

方法說明
next() / previous()移動到下一行/上一行
first() / last()移動到首行/尾行
absolute(int row)移動到指定絕對行號(1-based)
relative(int rows)相對當前行移動(正向前、負向後)
beforeFirst() / afterLast()移動到首行前/尾行後(無效行位置)
isFirst() / isLast() / isBeforeFirst() / isAfterLast()判斷游標位置

五、數據更新操作模式

1. 修改現有行

rs.absolute(5); // 定位到第 5 行
rs.updateString("name", "New Name"); // 修改列
rs.updateInt("age", 25);
rs.updateRow(); // 提交到數據庫,**游標不得離開當前行**

2. 插入新行

rs.moveToInsertRow(); // 移動到插入緩衝區
rs.updateString("name", "Inserted");
rs.updateInt("age", 30);
rs.insertRow(); // 寫入數據庫
rs.moveToCurrentRow(); // 返回原游標位置

3. 刪除當前行

rs.absolute(3);
rs.deleteRow(); // 立即刪除,游標移動到下一行

4. 取消修改

rs.updateString("name", "Wrong");
rs.cancelRowUpdates(); // 撤銷對當前行的所有 update,需在 updateRow() 前調用

六、行狀態檢測

rs.rowUpdated(); // 當前行是否被更新
rs.rowInserted(); // 當前行是否為新插入
rs.rowDeleted(); // 當前行是否被刪除(留有空位)

七、獲取數據:getXxx() 方法族

  • 按列索引(1-based)或列名:getInt(1)、getString("name")。
  • 基本類型返回默認值(0/false)而非 null;對象類型返回 null。
  • getString() 通用於所有類型,返回字符串表示。
  • 流式讀取大字段:getAsciiStream()、getBinaryStream()、getCharacterStream()。
  • 數組類型:getArray() 返回 java.sql.Array。

八、獲取模式常數(JDBC 2.0/3.0)

常數含義
FETCH_FORWARD順序處理(首→尾)
FETCH_REVERSE逆序處理(尾→首)
FETCH_UNKNOWN由驅動/數據庫決定
CONCUR_READ_ONLY只讀協作模式
CONCUR_UPDATABLE可更新協作模式
HOLD_CURSORS_OVER_COMMIT提交後保持游標打開
CLOSE_CURSORS_AT_COMMIT提交時關閉游標(默認)

九、最佳實踐與避坑指南

  1. 優先使用 TYPE_FORWARD_ONLY + CONCUR_READ_ONLY:性能最好、資源佔用最低,除非確需滾動/更新。
  2. 及時關閉:ResultSet、Statement、Connection 反序關閉,或用 try-with-resources(JDBC 4.1+)。
  3. 避免長事務中持有可更新 ResultSet:鎖定行時間過長導致並發下降。
  4. 批量插入用 PreparedStatement.addBatch(),而非 ResultSet.insertRow() 循環。
  5. MySQL 驅動提示:TYPE_SCROLL_SENSITIVE 實際表現為 INSENSITIVE;大結果集需設置 stmt.setFetchSize(Integer.MIN_VALUE) 啟用流式讀取避免 OOM。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved