JDBC 是 Java 應用存取 Oracle 的橋樑,用得好坏直接決定系統吞吐與穩定度。筆者多年實戰沉澱 10 大技巧,涵蓋驅動選型、事務控制、Statement/PreparedStatement 抉擇、動態 SQL、批量處理、LOB、預存程序呼叫、物件關聯映射、SQL 集合化思維,助你避開坑洼、榨乾效能。
Oracle 提供四類驅動:客戶端用 OCI(JNI 呼叫 Client Library)與 Thin(純 Java、直連);伺服器端用 Server-side Internal / Thin。官方文檔常推薦 OCI 以獲最高效能,但實測 Thin 驅動在大多數場景下效能優於 OCI,且部署零依賴、無 Client 安裝煩惱,升級維護極簡。結論:客戶端開發預設用 Thin。
新連線預設 autoCommit=true,每條 DML 皆隱含 Commit,產生大量網路交互與 Redo 產生。批量業務務必關閉:
conn.setAutoCommit(false);
搭配 conn.commit() / rollback() 手動管理,可將數萬筆 INSERT 從「逐筆提交」合併為「單次提交」,效能提升數量級。
常識以為 PreparedStatement 預編譯快於 Statement。但客戶端單次/低頻執行、或極其講究首次回應延遲的動態 SQL,Statement 反而更快(省去準備階段網路往返)。動態 SQL 拼接字串也更直觀。批量、高頻、固定模板才用 PreparedStatement。
拼接 SQL 易出單引號、日期格式錯誤。封裝 escapeSql(String)(單引號轉義)、toOracleDate(Date)(輸出 TO_DATE('yyyy-mm-dd hh24:mi:ss','...'))等工具方法,集中處理格式與防注入邏輯,業務碼乾淨安全。
企業級應用大量重複 SQL,PreparedStatement 讓庫端共用 Cursor、省去 Hard Parse、減少 Shared Pool 壓力、降低 Latch 競爭。雖客戶端首次準備稍慢,但整體系統吞吐顯著提升。除動態 SQL 外,預設首選 PreparedStatement。
標準 JDBC addBatch()/executeBatch() 通用但非最優。Oracle 專有 setExecuteBatch(n) 配合 executeUpdate() 效能最強:
((OraclePreparedStatement)pstmt).setExecuteBatch(30);
for (...) { pstmt.setXxx(...); pstmt.executeUpdate(); } // 積滿 30 筆自動發送
pstmt.sendBatch(); // 強制刷新剩餘
減少網路往返、降低 Redo 產生、提升寫入吞吐數倍。
Thin 驅動不支援 setBinaryStream/setCharacterStream 寫 LOB。 僅 Locator 方式可靠:SELECT ... FOR UPDATE 取得 Locator → getBinaryOutputStream()/getCharacterOutputStream() 寫入 → COMMIT。讀取同理。統一用 Locator 避免驅動版本差異坑。
{call ...}Oracle 允許 PL/SQL 區塊 BEGIN proc(); END; 或 SQL92 {call proc()}。統一用 SQL92:可攜性佳、工具解析友善、維護者無需懂 PL/SQL 包裝語法。
勿只在 Java 端建 Bean 對應關聯表。利用 Oracle 物件型別 CREATE TYPE ... AS OBJECT、CREATE TABLE ... OF TYPE 將領域模型與行為(方法)下沉資料庫,再用 JPublisher 產生 Java 類。優勢:多語言應用共享同一領域邏輯、資料完整性由資料庫保障、減少應用層碼量。
「用集合思維寫 SQL,而非程序思維寫 Java」。例:多表關聯更新、複雜聚合、階層查詢,單條 MERGE/WITH/CONNECT BY/MODEL 即可完成。資料不出庫,網路零開銷,CPU 留給資料庫專業引擎。 深鑽 SQL 進階特性,是 Java 開發者效能躍升的終極鑰匙。
| 場景 | 建議 |
|---|---|
| 客戶端驅動 | Thin (ojdbc8/11.jar) |
| 批量寫入 | PreparedStatement + setExecuteBatch |
| 單次/動態 SQL | Statement + Helper 格式化 |
| 高併發核心查詢 | PreparedStatement + 綁定變數 |
| LOB 讀寫 | Locator API (FOR UPDATE + Stream) |
| 預存程序 | SQL92 {call ...} |
| 領域模型 | Object Types + JPublisher |
| 複雜邏輯 | 單一 SQL / PL/SQL 包 |
掌握這 10 招,JDBC 層不再是瓶頸,反而成效能加速器。