Class.forName("oracle.jdbc.driver.OracleDriver"):最常用,靜態區塊自動向 DriverManager 註冊。但 Microsoft JVM(如 IE Applet)無法正確初始化。jdbc.drivers=oracle.jdbc.driver.OracleDriver,啟動時 java -Djdbc.drivers=... 或程式中 System.getProperties().load(...)。優點:換資料庫不改代碼,支援多驅動並載。DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()):最可靠,任何環境(含 Applet、Servlet)皆適用,缺點:寫死驅動類別,靈活性較低。建議:一般應用用 1;Applet/特殊環境用 3;需動態切換資料庫用 2。
標準 JDBC 2.0 不支援直接向 BLOB 寫入二進位流,嘗試會拋出 IO 錯誤而非 SQL 錯誤,極易誤判。
CREATE TABLE TB_FILE (NAME VARCHAR(20), DETAIL LONG RAW);
File file = new File("aaa.gif");
InputStream fin = new FileInputStream(file);
PreparedStatement pstmt = con.prepareStatement("INSERT INTO TB_FILE VALUES(?,?)");
pstmt.setString(1, "aaa.gif");
pstmt.setBinaryStream(2, fin, (int)file.length());
pstmt.executeUpdate();
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()) {
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1);
OutputStream out = blob.getBinaryOutputStream();
byte[] buf = new byte[blob.getBufferSize()];
InputStream fin = new FileInputStream(file);
int len;
while ((len = fin.read(buf)) != -1) out.write(buf, 0, len);
fin.close(); out.close();
con.commit();
}
讀取時:Blob blob = rs.getBlob("DETAIL"); InputStream in = blob.getBinaryStream();,不可用 rs.getBinaryStream("DETAIL")。
ResultSet.TYPE_SCROLL_INSENSITIVE 是由驅動程式在客戶端記憶體完整緩存結果集模擬出來的。ROWNUM)或游標分批取回,勿使用可捲動結果集。這三個問題在網路教學文中錯誤率極高,甚至官方文件也有誤導。實作驗證才是唯一標準,切勿盲目複製貼上。