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

JDBC 核心教學:ResultSet 完整操作指南與資料類型映射表

     編輯:Java 相關知識

ResultSet 核心概念

ResultSet 封裝 SQL 查詢結果集,維護一個游標指向當前資料列。初始位於第一列之前,呼叫 next() 移動到下一列並返回 true,直到結束返回 false。

基本遍歷模式

try (Connection conn = dataSource.getConnection();
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery("SELECT id, name, salary FROM employees")) {

    while (rs.next()) {
        int id = rs.getInt("id");           // 或 rs.getInt(1)
        String name = rs.getString("name"); // 建議用欄位名,可讀性高
        double salary = rs.getDouble("salary");
        System.out.printf("ID: %d, Name: %s, Salary: %.2f%n", id, name, salary);
    }
}

游標與併發型態 (JDBC 2.0+)

類型常數游標移動性可更新性適用場景
TYPE_FORWARD_ONLY僅向前唯讀預設、效能最好、串流處理大量資料
TYPE_SCROLL_INSENSITIVE雙向捲動唯讀需隨機存取、不需看見他人修改
TYPE_SCROLL_SENSITIVE雙向捲動可更新需即時反映他人修改、開銷大
// 建立可捲動、可更新的 ResultSet
Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_UPDATABLE
);

欄位存取:索引 vs 名稱

  • 索引 (1-based):效能稍佳、適用 SELECT * 或衍生欄位無名稱情況。
  • 名稱:可讀性高、不怕欄位順序變更、不區分大小寫。
  • 重複欄位名:getString("name") 只返回第一個匹配,必須用索引區分。

JDBC 資料類型映射完整對照表 (核心參考)

X = 推薦、x = 合法但不推薦、空白 = 不支援

JDBC TypegetBytegetShortgetIntgetLonggetFloatgetDoublegetBigDecimalgetBooleangetStringgetBytesgetDategetTimegetTimestampgetAsciiStreamgetUnicodeStreamgetBinaryStreamgetObject
BITxxxxxxxXxx
TINYINTXxxxxxxxxx
SMALLINTxXxxxxxxxx
INTEGERxxXxxxxxxx
BIGINTxxxXxxxxxx
REALxxxxXxxxxx
FLOAT/DOUBLExxxxxXxxxx
DECIMAL/NUMERICxxxxxxXxxx
CHAR/VARCHAR/LONGVARCHARxxxxxxxxXxXXx
BINARY/VARBINARY/LONGVARBINARYxXXx
DATExXxxx
TIMExxXxx
TIMESTAMPxxxXx

大型資料流式讀取 (避免記憶體溢位)

  • getBinaryStream():原始位元組流 (BLOB, LONGVARBINARY)。
  • getAsciiStream():單位元組字符流 (CLOB, LONGVARCHAR)。
  • getCharacterStream() (JDBC 2.0+):字符流 (取代 getUnicodeStream)。
// 4KB 緩衝區分塊讀取 CLOB
try (InputStream in = rs.getAsciiStream("content");
     OutputStream out = new FileOutputStream("dump.txt")) {
    byte[] buf = new byte[4096];
    int len;
    while ((len = in.read(buf)) != -1) {
        out.write(buf, 0, len);
    }
}
// 注意:流必須立即讀取,下一次 getXXX 呼叫會自動關閉前一個流!

NULL 值處理:wasNull() 陷阱

int value = rs.getInt("nullable_column");
if (rs.wasNull()) {
    // 資料庫是 NULL,getInt 返回 0
    value = -1; // 業務預設值
}

// 物件類型 getString/getObject 返回 null 直接判斷即可
String name = rs.getString("name");
if (name == null) { /* 是 NULL */ }
getXXX 類型資料庫 NULL 返回值wasNull() 返回
物件類型 (String, BigDecimal, Date, ...)nulltrue
基本數值類型 (byte, short, int, long, float, double)0true
booleanfalsetrue

多結果集處理 (預存程序/批次 SQL)

boolean hasResults = stmt.execute(unknownSql); // 可能返回多結果集/更新計數

while (true) {
    int updateCount = stmt.getUpdateCount();
    if (updateCount > 0) {
        System.out.println("Rows affected: " + updateCount);
        stmt.getMoreResults(); // 檢查下一個結果
        continue;
    }
    if (updateCount == 0) { // DDL 或 0 筆更新
        stmt.getMoreResults();
        continue;
    }
    // updateCount == -1 表示可能是 ResultSet
    ResultSet rs = stmt.getResultSet();
    if (rs != null) {
        // 處理 ResultSet...
        while (rs.next()) { /* ... */ }
        stmt.getMoreResults();
        continue;
    }
    // 兩者皆無 → 結束
    break;
}

資源管理鐵律

  • ResultSet、Statement、Connection 必須在 finally 區塊或 try-with-resources 中關閉。
  • 關閉 Statement 會自動關閉其產生的 ResultSet。
  • 連線池環境下,conn.close() 是歸還連線而非物理斷開。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved