首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

JDBC 處理資料庫 NULL 值陷阱:wasNull() 正確用法

     編輯:Oracle 資料庫基礎

問題根源:型別系統不匹配

  • 關聯式資料庫:任何型別皆可為 NULL (代表未知/缺值)
  • Java 基本型別 (int, long, double...):**不可為 null**,只有物件參考可為 null
  • JDBC ResultSet.getInt() 等基本型別取值方法:若資料庫欄位為 NULL,回傳值**由驅動程式決定** (可能是 0、預設值、上一筆值...),行為不可預期

標準解決模式:wasNull() 檢查

int idx = rs.getInt(1);          // 1. 先取值
if (rs.wasNull()) {              // 2. 立即檢查上一次 getXxx 是否為 NULL
    idx = -1;                    // 3. 套用應用層預設值 (如 -1 表「無資料」)
}

關鍵規則

  1. 順序固定:必須在同一個 getXxx() 呼叫緊接著呼叫 wasNull(),中間不可插入其他 JDBC 呼叫
  2. 僅適用基本型別 getter:getInt/getLong/getDouble/getFloat/getBoolean/getByte/getShort;物件型別 getString(), getObject() 直接回傳 null 參考,無需 wasNull()
  3. 驅動程式相容性:JDBC 規範要求所有標準驅動支援,但舊版/第三方驅動偶有 Bug,建議單元測試驗證

完整範例:安全讀取多種型別

public class SafeResultSetReader {
    public static Integer getIntOrNull(ResultSet rs, int col) throws SQLException {
        int val = rs.getInt(col);
        return rs.wasNull() ? null : val;
    }
    public static Long getLongOrNull(ResultSet rs, int col) throws SQLException {
        long val = rs.getLong(col);
        return rs.wasNull() ? null : val;
    }
    public static Double getDoubleOrNull(ResultSet rs, int col) throws SQLException {
        double val = rs.getDouble(col);
        return rs.wasNull() ? null : val;
    }
    // 使用範例
    public void process(ResultSet rs) throws SQLException {
        Integer salary = getIntOrNull(rs, 3);
        if (salary != null) {
            System.out.println("薪資: " + salary);
        } else {
            System.out.println("薪資欄位為 NULL");
        }
    }
}

常見錯誤模式

錯誤代碼問題正確做法
if (rs.getInt(1) == 0) ...無法區分「真實 0」與「NULL 轉 0」用 wasNull() 區分
int v = rs.getInt(1); ... other code ... if (rs.wasNull())中間插入其他 JDBC 呼叫導致 wasNull() 狀態重置緊接著檢查
String s = rs.getString(1); if (rs.wasNull())getString 回傳 null 參考,wasNull() 永遠 false直接 if (s == null)

現代框架處理

  • JPA/Hibernate:基本型別欄位建議用包裝型別 (Integer, Long) 直接映射 NULL → null
  • MyBatis:resultMap 指定 javaType="Integer" 自動處理
  • Spring JdbcTemplate:queryForObject(sql, Integer.class) 自動轉換 NULL → null (需注意基本型別會拋異常)

最佳實務總結

  1. 資料庫欄位允許 NULL 時,Java 端對應欄位**優先使用包裝型別**
  2. 若必須用基本型別,嚴格遵循 getXxx() → wasNull() → 套用預設值 三步驟
  3. 建立通用工具方法 (SafeResultSetReader) 統一處理,避免分散重複邏輯
  4. 單元測試覆蓋 NULL/非 NULL 兩種情境
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved