存儲過程將持久層邏輯下沉,分離業務邏輯,提升復用、安全、性能。Oracle 8i+ 內置 JVM (OJVM) 支持 Java 存儲過程,提供開放標準 (ANSI SQLJ)、跨平台可移植性、豐富生態庫,補足 PL/SQL 在網絡、XML、Web Service、複雜計算上的短板。
OJVM 無全局鎖爭用,會話狀態私有化,隨 CPU 核心線性擴展,無「JVM 單點瓶頸」。
不像外部中間件需單獨 Java 進程,OJVM 寄生於 Oracle 影子進程,內存佔用極低,管理零成本。
| 維度 | PL/SQL | Java |
|---|---|---|
| SQL 集成 | 無縫、原生、隱式游標、FORALL 批量 | 需 JDBC 顯式連接、準備語句、結果集映射 |
| 數據類型映射 | 原生一致 | 需類型轉換 (oracle.sql.* / JDBC 映射) |
| 計算密集型邏輯 | 弱 (解釋執行) | 強 (JIT 編譯、多線程、豐富庫) |
| 外部交互 | 受限 (UTL_HTTP、DBMS_PIPE) | 強 (Socket、HTTP Client、JMS、JCA、加密庫) |
| XML/JSON 處理 | XMLType/XQuery 支持尚可、JSON 12c+ 增強 | 生態最豐富 (Jackson、JAXB、DOM/SAX/StAX) |
| 部署/版本管理 | 需 loadjava/resolve、版本兼容性檢查 | |
| 調試體驗 | PL/SQL Developer 等原生支持好 | 需遠程調試端口、IDE 配置較繁 |
loadjava -u scott/tiger@orcl -v -resolve MyClass.class
# 或加載 JAR
loadjava -u scott/tiger@orcl -v -resolve mylib.jar
CREATE OR REPLACE PROCEDURE my_java_proc(p_input VARCHAR2)
AS LANGUAGE JAVA
NAME 'MyClass.myStaticMethod(java.lang.String)';
/
CREATE OR REPLACE FUNCTION my_java_func(p_id NUMBER) RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'MyClass.myStaticFunc(int) return java.lang.String';
/
DriverManager.getConnection("jdbc:default:connection:") 獲取當前會話事務上下文,不提交/回滾,由調用者控制。System.out/err → DBMS_JAVA.SET_OUTPUT → `DBMS_OUTPUT`,便於調試。DBMS_JAVA.GRANT_PERMISSION 精細控制文件/網絡/屬性訪問,遵循最小權限原則。RESOLVER 指定模式搜索順序,類似 CLASSPATH 但按類粒度控制。OJVM 將成熟的 Java 生態引入數據庫內核,以會話隔離、共享代碼、線性擴展架構解決了「數據庫跑 Java 會不穩」的疑慮。選型核心:**PL/SQL 做數據,Java 做計算與集成,雙劍合璧構建極致存儲過程能力。**