| 方式 | 代碼 | 優缺點 |
|---|---|---|
| Class.forName | Class.forName("oracle.jdbc.driver.OracleDriver") | 簡單,但 MS JVM (IE Applet) 無法正確初始化靜態區塊 |
| 系統屬性檔 | System.getProperty().load(...); jdbc.drivers=oracle.jdbc.driver.OracleDriver | 可同時載入多驅動,切換 DB 無需改代碼 |
| DriverManager.registerDriver | DriverManager.registerDriver(new OracleDriver()) | 最可靠,任何環境(含 Applet)均可用 |
建議:生產環境採用方式 3 或 2+3 結合。
// 標準 JDBC 2.0 不支援直接 setBinaryStream 寫 BLOB
ps.setBinaryStream(1, fin, len); // 拋出 IO 異常而非 SQL 異常
// 1. 建表
CREATE TABLE tb_file(name VARCHAR2(20), detail BLOB);
// 2. 插入空 BLOB 取得 Locator
conn.setAutoCommit(false);
stmt.executeUpdate("INSERT INTO tb_file VALUES ('aaa.gif', EMPTY_BLOB())");
// 3. SELECT FOR UPDATE 取得 BLOB 物件
ResultSet rs = stmt.executeQuery("SELECT detail FROM tb_file WHERE name='aaa.gif' FOR UPDATE");
if (rs.next()) {
BLOB blob = ((OracleResultSet)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 len;
while ((len = fin.read(buf)) != -1) out.write(buf, 0, len);
fin.close(); out.close();
conn.commit();
}
BLOB blob = ((OracleResultSet)rs).getBLOB("detail");
InputStream in = blob.getBinaryStream(); // 而非 rs.getBinaryStream()
標準 JDBC 支援:ps.setBinaryStream(1, fin, len) 直接寫入,但 LONG RAW 已不推薦使用(單表僅一欄、操作限制多)。
ResultSet.TYPE_SCROLL_INSENSITIVE 是在**客戶端記憶體全量緩存**實現。ROWNUM 或 OFFSET/FETCH 12c+)。Java/Oracle 開發鐵律:用 registerDriver 載入驅動、BLOB 必須用 Oracle 擴充 API、可捲動結果集僅限小結果集、大數據分頁在 SQL 層解決。