正常載入驅動程式有三種途徑:
DriverManager.registerDriver(driver)。System.getProperties().load(new FileInputStream("屬性檔")),屬性檔中指定 jdbc.driver=drivername。優點:可同時載入多個 JDBC,換資料庫時不用修改 Java 原始碼,只需修改屬性檔。注意:方法 1 簡單但 MS JVM 無法正確初始化(如 IE 中 Applet 不可用),應用方法 3。但方法 3 彈性不如方法 2,可根據環境綜合考量。
大物件儲存通常指將檔案存入資料庫,當然也可為記憶體中超大字串。對圖片等二進位檔案應用二進位儲存。網路上 99% 教學不可行,連 Sun 官方文件也有錯誤。
若嘗試直接存入 BLOB,會得到 IO 而非 SQL 例外。
CREATE TABLE tb_file(name VARCHAR(20), detail LONG RAW);
File file = new File("aaa.gif");
int fileLength = (int) file.length();
InputStream fin = new FileInputStream(file);
PreparedStatement pstmt = con.prepareStatement("INSERT INTO tb_file VALUES('aaa.gif',?)");
pstmt.setBinaryStream(1, fin, fileLength);
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())");
// 必須 SELECT 取得 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[] b = new byte[((oracle.sql.BLOB)blob).getBufferSize()];
InputStream fin = new FileInputStream(file);
int len;
while ((len = fin.read(b)) != -1) out.write(b, 0, len);
fin.close(); out.close(); con.commit();
}
讀取時也不能像 LONG RAW 那樣用 rs.getBinaryStream("detail"),必須:
Blob blob = rs.getBlob("detail");
InputStream in = blob.getBinaryStream();
Oracle 明確說明不支援結果集捲動,JDBC 2 取得的可捲動結果集是 JDBC 自己在記憶體中高度快取,許多開發者誤以為是資料庫支援。若真查詢大量資料列,記憶體會耗盡。對超大量資料,寧願用笨方法也不要用可捲動結果集。