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

JDBC 2.0 進階數據類型實戰:Blob、Clob、Array、Ref 與 UDT

     編輯:Java 程式設計入門

概覽

JDBC 2.0 引入 SQL3 標準大對象與結構化類型支持,讓 Java 直接操作數據庫豐富類型:

  • Blob (Binary Large Object): 圖片、音視頻、二進制文檔。
  • Clob (Character Large Object): 大文本、XML、日誌。
  • Array: SQL 數組類型映射。
  • Ref: 物件引用 (OID)。
  • UDT (User-Defined Type): 自定義結構類型 (STRUCT)。

Blob 實戰:圖片存儲與讀取

插入圖片 (PreparedStatement.setBinaryStream)

String sql = "INSERT INTO tbl_User (username, photo) VALUES (?, ?)";
PreparedStatement pstmt = con.prepareStatement(sql);

File file = new File("C:/images/photo.jpg");
FileInputStream fis = new FileInputStream(file);

pstmt.setString(1, "John");
pstmt.setBinaryStream(2, fis, (int) file.length()); // 關鍵:流 + 長度

pstmt.executeUpdate();
pstmt.close();
fis.close();

讀取並顯示 (ResultSet.getBlob + getBytes)

String sql = "SELECT photo FROM tbl_User WHERE username = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "John");
ResultSet rs = pstmt.executeQuery();

if (rs.next()) {
    Blob blob = rs.getBlob("photo");
    byte[] imgBytes = blob.getBytes(1, (int) blob.length()); // 1-based 索引
    ImageIcon icon = new ImageIcon(imgBytes);
    JLabel photoLabel = new JLabel(icon);
    // 添加到 Swing 界面...
}
rs.close();
pstmt.close();

Clob 實戰:大文本存儲與讀取

插入文本 (setAsciiStream / setCharacterStream)

String sql = "INSERT INTO tbl_Articles (title, content) VALUES (?, ?)";
PreparedStatement pstmt = con.prepareStatement(sql);

File file = new File("C:/data/news.txt");
FileInputStream fis = new FileInputStream(file);
// 或使用 Reader: FileReader reader = new FileReader(file);

pstmt.setString(1, "Iraq War");
pstmt.setAsciiStream(2, fis, (int) file.length()); // ASCII 文本
// pstmt.setCharacterStream(2, reader, (int) file.length()); // 字符流 (含編碼)

pstmt.executeUpdate();
pstmt.close();
fis.close();

讀取文本 (getClob + getAsciiStream / getCharacterStream)

String sql = "SELECT content FROM tbl_Articles WHERE title = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "Iraq War");
ResultSet rs = pstmt.executeQuery();

if (rs.next()) {
    Clob clob = rs.getClob("content");
    // 方式 1: ASCII 流
    InputStreamReader in = new InputStreamReader(clob.getAsciiStream());
    // 方式 2: 字符流 (推薦,自動處理編碼)
    // Reader reader = clob.getCharacterStream();
    JTextArea textArea = new JTextArea(readString(in)); // 輔助方法讀取流
}
rs.close();
pstmt.close();

關鍵最佳實踐

  • 流式處理: 必須使用 setBinaryStream/setAsciiStream/setCharacterStream 避免將大對象完全載入 JVM 堆內存 (防 OOM)。
  • 長度參數: setXxxStream(stream, length) 的長度必須準確,部分驅動依賴它優化傳輸。
  • 資源關閉順序: 先關 ResultSet/Statement,再關流,最後關 Connection (若非連接池)。
  • 事務邊界: 大對象操作通常在事務中進行,確保原子性。
  • 數據庫差異: Oracle BLOB/CLOB 需先 empty_blob() 初始化;MySQL LONGBLOB/LONGTEXT 直接支持流式寫入;PostgreSQL 使用 BYTEA/TEXT + Large Object API。具體驅動行為請查閱廠商文檔。

Array / Ref / UDT 簡介

  • Array:ResultSet.getArray() 返回 java.sql.Array,getArray() 獲取 Java 數組,getResultSet() 獲取結果集逐行處理。
  • Ref:代表對象標識符 (OID),getObject() 可解析為具體結構對象。
  • Struct / UDT:getObject() 返回 java.sql.Struct,getAttributes() 取字段值數組。需配合 SQLData 接口實現自定義映射。

「這些新類型結合在一起,使得數據庫設計人員可以創建更豐富的模式,並簡化了對復雜數據的處理和持久化。」

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