首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 下開發 Java 應用三大關鍵議題:JDBC 載入、大物件存儲、可捲動游標

     編輯:Oracle 資料庫相關知識

問題一:JDBC 驅動程式載入三種方式

  1. Class.forName():最常見,載入類別並觸發靜態區塊向 DriverManager 註冊。但 Microsoft JVM (IE Applet) 無法正確初始化。
  2. 系統屬性檔:System.getProperty().load(...) 讀取屬性檔中的 jdbc.driver,優點是更換資料庫無需改動 Java 程式碼。
  3. DriverManager.registerDriver():直接註冊,最可靠,任何環境皆適用,但彈性較差。

建議:一般環境用 (1);Applet 或特殊環境用 (3);需動態切換資料庫用 (2)。

問題二:大物件 (BLOB) 存儲陷阱

標準 JDBC 2.0 無法直接對 BLOB 寫入二進位檔案,會拋出 IO Exception 而非 SQL Exception。正確做法有二:

方案 A:使用 LONG RAW (標準 JDBC)

CREATE TABLE tb_file(name VARCHAR(20), detail LONG RAW);
File file = new File("aaa.gif");
int len = (int) file.length();
InputStream fin = new FileInputStream(file);
PreparedStatement pstmt = con.prepareStatement("INSERT INTO tb_file VALUES('aaa.gif', ?)");
pstmt.setBinaryStream(1, fin, len);
pstmt.executeUpdate();

方案 B:使用 BLOB (Oracle 專有 API)

CREATE TABLE tb_file(name VARCHAR(20), detail BLOB);
con.setAutoCommit(false);
stmt.executeUpdate("INSERT INTO tb_file VALUES('aaa.gif', EMPTY_BLOB())");
ResultSet rs = stmt.executeQuery("SELECT detail FROM tb_file WHERE name='aaa.gif' FOR UPDATE");
if (rs.next()) {
    Blob blob = rs.getBlob(1);
    OutputStream out = ((oracle.sql.BLOB)blob).getBinaryOutputStream();
    byte[] buf = new byte[((oracle.sql.BLOB)blob).getBufferSize()];
    InputStream fin = new FileInputStream(file);
    int n;
    while ((n = fin.read(buf)) != -1) out.write(buf, 0, n);
    fin.close(); out.close(); con.commit();
}

讀取時亦須用 blob.getBinaryStream(),不可用 rs.getBinaryStream()。

問題三:可捲動結果集 = 記憶體災難

Oracle 明確不支援伺服器端游標捲動,JDBC 2.0 的 TYPE_SCROLL_INSENSITIVE 實際是將全部結果集緩存在客戶端記憶體。查詢大量資料時會導致 OOM。大量資料查詢請務必使用唯讀、順向游標,捨棄捲動功能。

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