在我的數據庫接口庫jOOQ中,我想添加對Oracle(或DB2等)包的支持。我已經實現了存儲過程/函數支持,每個存儲對象都被建模爲生成的Java類。例如,該存儲功能Oracle包和Java包之間的映射
CREATE FUNCTION f_author_exists (author_name VARCHAR2) RETURNS NUMBER;
將產生可以這樣使用一個類(注意,也有很多方便的方法,這個例子只是顯示了常規設計):
// A new "function call instance". The function needs to be instanciated
// once per call
FAuthorExists f = new FAuthorExists();
// Set the function parameters on the call instance and call it
f.setAuthorName("Paulo");
f.execute(connection);
// Fetch the result from the function call instance
BigDecimal result = f.getReturnValue();
我選擇映射的原因SQL函數→Java類是因爲存儲過程允許在調用過程後能夠一個接一個地讀取複雜的返回值(幾個OUT或IN OUT參數):
p.getOutParam1();
p.getOutParam2();
現在這種設計可以很好地與存儲的函數/程序一起工作,其中重載是不可能的。在甲骨文公司(或DB2的)封裝,但是,我可以有多個函數具有相同的名稱,如
CREATE PACKAGE my_package IS
FUNCTION f_author_exists (name VARCHAR2) RETURNS NUMBER;
FUNCTION f_author_exists (name VARCHAR2, country VARCHAR2) RETURNS NUMBER;
END my_package;
當我生成每個函數(或過程)的一類,我將有幾個FAuthorExists
Java類命名衝突。蹩腳的解決方案是爲類名添加索引,如FAuthorExists2
,FAuthorExists3
。另一個蹩腳的解決方案是從參數名稱/類型直接生成某種類型的散列值(或值本身),例如FAuthorExistsVARCHAR2
,FAuthorExistsVARCHAR2VARCHAR2
。出於顯而易見的原因,這兩種解決方案都不可取
有沒有人有這個問題的簡單解決方案?或者也許是一個更好的總體設計的想法,不會產生這樣的函數名稱超載問題?
任何反饋讚賞!
'execute()'方法進行實際的調用。由於函數參數「name」,該方法被稱爲'setName()'。我在例子中解決了這個問題,使其更加清晰。你的想法不錯。儘管如此,問題在於如果函數名稱重載的參數集非常不同,那麼可能會發現混淆,可能會有哪些參數組合。但是,通過便利的方法,這可能確實有效! +1爲在運行時確定正確調用的想法 – 2010-12-14 15:40:20
@Lukas匹配參數類型而不是名稱是我的建議 - 我認爲它可能更簡單。不過,我認爲原則上兩者都有可能。 – 2010-12-14 15:48:32
很容易找到一個關於如何根據參數名稱/類型/位置調用函數的好實現。但困難的部分是讓生成的代碼易於開發人員使用。這就是爲什麼我在生成的方法中使用參數的名稱 – 2010-12-14 16:36:02