?
?通過JDBC連接Oracle數據庫中的十大技巧
??
??
??
1
、在客
戶
端
軟
件
開發
中使用
Thin
驅動
程序
在 開發 Java 軟 件方面, Oracle 的數據 庫 提供了四 種類 型的 驅動 程序,二 種 用于 應 用 軟 件、 applets 、 servlets 等客 戶 端 軟 件,另外二 種 用于數據 庫 中的 Java 存 儲過 程等服 務 器端 軟 件。在客 戶 機端 軟 件的 開發 中,我 們 可以 選擇 OCI 驅動 程序或 Thin 驅動 程序。 OCI 驅動 程序利用 Java 本地化接口( JNI ),通 過 Oracle 客 戶 端 軟 件與數據 庫進 行通 訊 。 Thin 驅動 程序是 純 Java 驅動 程序,它直接與數據 庫進 行通 訊 。 為 了 獲 得最高的性能, Oracle 建 議 在客 戶 端 軟 件的 開發 中使用 OCI 驅動 程序, 這 似乎是正確的。但我建 議 使用 Thin 驅動 程序,因 為 通 過 多次 測試發現 ,在通常情況下, Thin 驅動 程序的性能都超 過 了 OCI 驅動 程序。
2 、 關閉 自 動 提交功能,提高系 統 性能
在第一次建立與數據 庫 的 連 接 時 ,在缺省情況下, 連 接是在自 動 提交模式下的。 為 了 獲 得更好的性能,可以通 過調 用 帶 布 爾 值 false 參數的 Connection 類 的 setAutoCommit() 方法 關閉 自 動 提交功能,如下所示:
conn.setAutoCommit(false);
值 得注意的是,一旦 關閉 了自 動 提交功能,我 們 就需要通 過調 用 Connection 類 的 commit() 和 rollback() 方法來人工的方式 對 事 務進 行管理。
3 、在 動態 SQL 或有 時間 限制的命令中使用 Statement 對 象
在 執 行 SQL 命令 時 ,我 們 有二 種選擇 :可以使用 PreparedStatement 對 象,也可以使用 Statement 對 象。無 論 多少次地使用同一個 SQL 命令, PreparedStatement 都只 對 它解析和 編譯 一次。當使用 Statement 對 象 時 , 每 次 執 行一個 SQL 命令 時 ,都會 對 它 進 行解析和 編譯 。 這 可能會使你 認為 ,使用 PreparedStatement 對 象比使用 Statement 對 象的速度更快。然而,我 進 行的 測試 表明,在客 戶 端 軟 件中,情況并非如此。 因此,在有 時間 限制的 SQL 操作中,除非成批地 處 理 SQL 命令,我 們應 當考 慮 使用 Statement 對 象。
此外,使用 Statement 對 象也使得 編 寫 動態 SQL 命令更加 簡單 ,因 為 我 們 可以將字符串 連 接在一起,建立一個有效的 SQL 命令。因此,我 認為 , Statement 對 象可以使 動態 SQL 命令的 創 建和 執 行 變 得更加 簡單 。
4 、利用 helper 函數 對動態 SQL 命令 進 行格式化
在 創 建使用 Statement 對 象 執 行的 動態 SQL 命令 時 ,我 們 需要 處 理一些格式化方面的 問題 。例如,如果我 們 想 創 建一個將名字 O'Reilly 插入表中的 SQL 命令, 則 必 須 使用二個相 連 的 “''” 號替 換 O'Reilly 中的 “'” 號。完成 這 些工作的最好的方法是 創 建一個完成替 換 操作的 helper 方法,然后在 連 接字符串心服用公式表達一個 SQL 命令 時 ,使用 創 建的 helper 方法。 與此 類 似的是,我 們 可以 讓 helper 方法接受一個 Date 型的 值 ,然后 讓 它 輸 出基于 Oracle 的 to_date() 函數的字符串表達式。
5 、利用 PreparedStatement 對 象提高數據 庫 的 總 體效率
在使用 PreparedStatement 對 象 執 行 SQL 命令 時 ,命令被數據 庫進 行解析和 編譯 ,然后被放到命令 緩 沖區。然后, 每 當 執 行同一個 PreparedStatement 對 象 時 ,它就會被再解析一次,但不會被再次 編譯 。在 緩 沖區中可以 發現預編譯 的命令,并且可以重新使用。在有大量用 戶 的企 業級應 用 軟 件中, 經 常會重 復執 行相同的 SQL 命令,使用 PreparedStatement 對 象 帶 來的 編譯 次數的減少能 夠 提高數據 庫 的 總 體性能。如果不是在客 戶 端 創 建、 預備 、 執 行 PreparedStatement 任 務 需要的 時間長 于 Statement 任 務 ,我會建 議 在除 動態 SQL 命令之外的所有情況下使用 PreparedStatement 對 象。
6 、在成批 處 理重 復 的插入或更新操作中使用 PreparedStatement 對 象
如果成批地 處 理插入和更新操作,就能 夠顯 著地減少它 們 所需要的 時間 。 Oracle 提供的 Statement 和 CallableStatement 并不真正地支持批 處 理,只有 PreparedStatement 對 象才真正地支持批 處 理。我 們 可以使用 addBatch() 和 executeBatch() 方法 選擇標 準的 JDBC 批 處 理,或者通 過 利用 PreparedStatement 對 象的 setExecuteBatch() 方法和 標 準的 executeUpdate() 方法 選擇 速度更快的 Oracle 專 有的方法。要使用 Oracle 專 有的批 處 理機制,可以以如下所示的方式 調 用 setExecuteBatch() :
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);
...
pstmt.executeUpdate();
}
調 用 setExecuteBatch() 時 指定的 值 是一個上限,當達到 該值時 ,就會自 動 地引 發 SQL 命令 執 行, 標 準的 executeUpdate() 方法就會被作 為 批 處 理送到數據 庫 中。我 們 可以通 過調 用 PreparedStatement 類 的 sendBatch() 方法隨 時傳輸 批 處 理任 務 。
7 、使用 Oracle locator 方法插入、更新大 對 象( LOB )
Oracle 的 PreparedStatement 類 不完全支持 BLOB 和 CLOB 等大 對 象的 處 理,尤其是 Thin 驅動 程序不支持利 用 PreparedStatement 對 象的 setObject() 和 setBinaryStream() 方法 設 置 BLOB 的 值 ,也不支持利用 setCharacterStream() 方法 設 置 CLOB 的 值 。只有 locator 本身中的方法才能 夠 從數據 庫 中 獲 取 LOB 類 型的 值 。可以使用 PreparedStatement 對 象插入或更新 LOB ,但需要使用 locator 才能 獲 取 LOB 的 值 。由于存在 這 二個 問題 ,因此,我建 議 使用 locator 的方法來插入、更新或 獲 取 LOB 的 值 。
8 、使用 SQL92 語 法 調 用存 儲過 程
在 調 用 存 儲過 程 時 ,我 們 可以使用 SQL92 或 Oracle PL/SQL ,由于使用 Oracle PL/SQL 并沒有什 么實際 的好 處 ,而且會 給 以后 維護 你的 應 用程序的 開發 人 員帶 來麻 煩 ,因此,我建 議 在 調 用存 儲過 程 時 使用 SQL92 。
9 、使用 Object SQL 將 對 象模式 轉 移到數據 庫 中
既然可以將 Oracle 的數據 庫 作 為 一 種 面向 對 象的數據 庫 來使用,就可以考 慮 將 應 用程序中的面向 對 象模式 轉 到數據 庫 中。目前的方法是 創 建 Java bean 作 為偽 裝的數據 庫對 象,將它 們 的屬性映射到 關 系表中,然后在 這 些 bean 中添加方法。盡管 這樣 作在 Java 中沒有什 么問題 ,但由于操作都是在數據 庫 之外 進 行的,因此其他 訪問 數據 庫 的 應 用 軟 件無法利用 對 象模式。如果利用 Oracle 的面向 對 象的技 術 ,可以通 過創 建一個新的數據 庫對 象 類 型在數據 庫 中模仿其數據和操作,然后使用 JPublisher 等工具生成自己的 Java bean 類 。如果使用 這種 方式,不但 Java 應 用程序可以使用 應 用 軟 件的 對 象模式,其他需要共享你的 應 用中的數據和操作的 應 用 軟 件也可以使用 應 用 軟 件中的 對 象模式。
10 、利用 SQL 完成數據 庫 內的操作
我要向大家介 紹 的最重要的 經驗 是充分利用 SQL 的面向集合的方法來解決數據 庫處 理需求,而不是使用 Java 等 過 程化的 編 程 語 言。
如果 編 程人 員 要在一個表中 查 找 許 多行, 結 果中的 每 個行都會 查 找其他表中的數據,最后, 編 程人 員創 建了獨立的 UPDATE 命令來成批地更新第一個表中的數據。與此 類 似的任 務 可以通 過 在 set 子句中使用多列子 查詢 而在一個 UPDATE 命令中完成。當能 夠 在 單 一的 SQL 命令中完成任 務 ,何必要 讓 數據在網上流來流去的?我建 議 用 戶認 真學 習 如何最大限度地 發揮 SQL 的功能 ?
在 開發 Java 軟 件方面, Oracle 的數據 庫 提供了四 種類 型的 驅動 程序,二 種 用于 應 用 軟 件、 applets 、 servlets 等客 戶 端 軟 件,另外二 種 用于數據 庫 中的 Java 存 儲過 程等服 務 器端 軟 件。在客 戶 機端 軟 件的 開發 中,我 們 可以 選擇 OCI 驅動 程序或 Thin 驅動 程序。 OCI 驅動 程序利用 Java 本地化接口( JNI ),通 過 Oracle 客 戶 端 軟 件與數據 庫進 行通 訊 。 Thin 驅動 程序是 純 Java 驅動 程序,它直接與數據 庫進 行通 訊 。 為 了 獲 得最高的性能, Oracle 建 議 在客 戶 端 軟 件的 開發 中使用 OCI 驅動 程序, 這 似乎是正確的。但我建 議 使用 Thin 驅動 程序,因 為 通 過 多次 測試發現 ,在通常情況下, Thin 驅動 程序的性能都超 過 了 OCI 驅動 程序。
2 、 關閉 自 動 提交功能,提高系 統 性能
在第一次建立與數據 庫 的 連 接 時 ,在缺省情況下, 連 接是在自 動 提交模式下的。 為 了 獲 得更好的性能,可以通 過調 用 帶 布 爾 值 false 參數的 Connection 類 的 setAutoCommit() 方法 關閉 自 動 提交功能,如下所示:
conn.setAutoCommit(false);
值 得注意的是,一旦 關閉 了自 動 提交功能,我 們 就需要通 過調 用 Connection 類 的 commit() 和 rollback() 方法來人工的方式 對 事 務進 行管理。
3 、在 動態 SQL 或有 時間 限制的命令中使用 Statement 對 象
在 執 行 SQL 命令 時 ,我 們 有二 種選擇 :可以使用 PreparedStatement 對 象,也可以使用 Statement 對 象。無 論 多少次地使用同一個 SQL 命令, PreparedStatement 都只 對 它解析和 編譯 一次。當使用 Statement 對 象 時 , 每 次 執 行一個 SQL 命令 時 ,都會 對 它 進 行解析和 編譯 。 這 可能會使你 認為 ,使用 PreparedStatement 對 象比使用 Statement 對 象的速度更快。然而,我 進 行的 測試 表明,在客 戶 端 軟 件中,情況并非如此。 因此,在有 時間 限制的 SQL 操作中,除非成批地 處 理 SQL 命令,我 們應 當考 慮 使用 Statement 對 象。
此外,使用 Statement 對 象也使得 編 寫 動態 SQL 命令更加 簡單 ,因 為 我 們 可以將字符串 連 接在一起,建立一個有效的 SQL 命令。因此,我 認為 , Statement 對 象可以使 動態 SQL 命令的 創 建和 執 行 變 得更加 簡單 。
4 、利用 helper 函數 對動態 SQL 命令 進 行格式化
在 創 建使用 Statement 對 象 執 行的 動態 SQL 命令 時 ,我 們 需要 處 理一些格式化方面的 問題 。例如,如果我 們 想 創 建一個將名字 O'Reilly 插入表中的 SQL 命令, 則 必 須 使用二個相 連 的 “''” 號替 換 O'Reilly 中的 “'” 號。完成 這 些工作的最好的方法是 創 建一個完成替 換 操作的 helper 方法,然后在 連 接字符串心服用公式表達一個 SQL 命令 時 ,使用 創 建的 helper 方法。 與此 類 似的是,我 們 可以 讓 helper 方法接受一個 Date 型的 值 ,然后 讓 它 輸 出基于 Oracle 的 to_date() 函數的字符串表達式。
5 、利用 PreparedStatement 對 象提高數據 庫 的 總 體效率
在使用 PreparedStatement 對 象 執 行 SQL 命令 時 ,命令被數據 庫進 行解析和 編譯 ,然后被放到命令 緩 沖區。然后, 每 當 執 行同一個 PreparedStatement 對 象 時 ,它就會被再解析一次,但不會被再次 編譯 。在 緩 沖區中可以 發現預編譯 的命令,并且可以重新使用。在有大量用 戶 的企 業級應 用 軟 件中, 經 常會重 復執 行相同的 SQL 命令,使用 PreparedStatement 對 象 帶 來的 編譯 次數的減少能 夠 提高數據 庫 的 總 體性能。如果不是在客 戶 端 創 建、 預備 、 執 行 PreparedStatement 任 務 需要的 時間長 于 Statement 任 務 ,我會建 議 在除 動態 SQL 命令之外的所有情況下使用 PreparedStatement 對 象。
6 、在成批 處 理重 復 的插入或更新操作中使用 PreparedStatement 對 象
如果成批地 處 理插入和更新操作,就能 夠顯 著地減少它 們 所需要的 時間 。 Oracle 提供的 Statement 和 CallableStatement 并不真正地支持批 處 理,只有 PreparedStatement 對 象才真正地支持批 處 理。我 們 可以使用 addBatch() 和 executeBatch() 方法 選擇標 準的 JDBC 批 處 理,或者通 過 利用 PreparedStatement 對 象的 setExecuteBatch() 方法和 標 準的 executeUpdate() 方法 選擇 速度更快的 Oracle 專 有的方法。要使用 Oracle 專 有的批 處 理機制,可以以如下所示的方式 調 用 setExecuteBatch() :
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);
...
pstmt.executeUpdate();
}
調 用 setExecuteBatch() 時 指定的 值 是一個上限,當達到 該值時 ,就會自 動 地引 發 SQL 命令 執 行, 標 準的 executeUpdate() 方法就會被作 為 批 處 理送到數據 庫 中。我 們 可以通 過調 用 PreparedStatement 類 的 sendBatch() 方法隨 時傳輸 批 處 理任 務 。
7 、使用 Oracle locator 方法插入、更新大 對 象( LOB )
Oracle 的 PreparedStatement 類 不完全支持 BLOB 和 CLOB 等大 對 象的 處 理,尤其是 Thin 驅動 程序不支持利 用 PreparedStatement 對 象的 setObject() 和 setBinaryStream() 方法 設 置 BLOB 的 值 ,也不支持利用 setCharacterStream() 方法 設 置 CLOB 的 值 。只有 locator 本身中的方法才能 夠 從數據 庫 中 獲 取 LOB 類 型的 值 。可以使用 PreparedStatement 對 象插入或更新 LOB ,但需要使用 locator 才能 獲 取 LOB 的 值 。由于存在 這 二個 問題 ,因此,我建 議 使用 locator 的方法來插入、更新或 獲 取 LOB 的 值 。
8 、使用 SQL92 語 法 調 用存 儲過 程
在 調 用 存 儲過 程 時 ,我 們 可以使用 SQL92 或 Oracle PL/SQL ,由于使用 Oracle PL/SQL 并沒有什 么實際 的好 處 ,而且會 給 以后 維護 你的 應 用程序的 開發 人 員帶 來麻 煩 ,因此,我建 議 在 調 用存 儲過 程 時 使用 SQL92 。
9 、使用 Object SQL 將 對 象模式 轉 移到數據 庫 中
既然可以將 Oracle 的數據 庫 作 為 一 種 面向 對 象的數據 庫 來使用,就可以考 慮 將 應 用程序中的面向 對 象模式 轉 到數據 庫 中。目前的方法是 創 建 Java bean 作 為偽 裝的數據 庫對 象,將它 們 的屬性映射到 關 系表中,然后在 這 些 bean 中添加方法。盡管 這樣 作在 Java 中沒有什 么問題 ,但由于操作都是在數據 庫 之外 進 行的,因此其他 訪問 數據 庫 的 應 用 軟 件無法利用 對 象模式。如果利用 Oracle 的面向 對 象的技 術 ,可以通 過創 建一個新的數據 庫對 象 類 型在數據 庫 中模仿其數據和操作,然后使用 JPublisher 等工具生成自己的 Java bean 類 。如果使用 這種 方式,不但 Java 應 用程序可以使用 應 用 軟 件的 對 象模式,其他需要共享你的 應 用中的數據和操作的 應 用 軟 件也可以使用 應 用 軟 件中的 對 象模式。
10 、利用 SQL 完成數據 庫 內的操作
我要向大家介 紹 的最重要的 經驗 是充分利用 SQL 的面向集合的方法來解決數據 庫處 理需求,而不是使用 Java 等 過 程化的 編 程 語 言。
如果 編 程人 員 要在一個表中 查 找 許 多行, 結 果中的 每 個行都會 查 找其他表中的數據,最后, 編 程人 員創 建了獨立的 UPDATE 命令來成批地更新第一個表中的數據。與此 類 似的任 務 可以通 過 在 set 子句中使用多列子 查詢 而在一個 UPDATE 命令中完成。當能 夠 在 單 一的 SQL 命令中完成任 務 ,何必要 讓 數據在網上流來流去的?我建 議 用 戶認 真學 習 如何最大限度地 發揮 SQL 的功能 ?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
