6

在我的数据库接口库jOOQ中,我想添加对 Oracle(或 DB2 等)包的支持。我已经实现了存储过程/函数支持,其中每个存储对象都被建模为生成的 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();

现在,这种设计适用于无法重载的存储函数/过程。然而,在 Oracle(或 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;

当我为每个函数(或过程)生成一个类时,我将与几个FAuthorExistsJava 类发生命名冲突。一个蹩脚的解决方案是在类名中添加一个索引,例如FAuthorExists2, FAuthorExists3。另一个蹩脚的解决方案是从参数名称/类型直接生成某种哈希值(或值本身)到类名中,例如FAuthorExistsVARCHAR2, FAuthorExistsVARCHAR2VARCHAR2. 出于显而易见的原因,这两种解决方案都是不可取的。

有没有人有一个简单的解决方案来解决这个问题?或者也许是一个更好的整体设计的想法,它不会产生这样的函数名称重载问题?

任何反馈表示赞赏!

4

3 回答 3

3

您的getReturnValue函数可以在调用时根据设置了多少输入参数来确定要调用哪个重载函数 - 但我认为如果您坚持使用类似setParam1而不是setName

于 2010-12-14T14:25:31.580 回答
0

除了在生成的类上使用“重载索引”之外,我没有发现其他可行的方法来解决这个问题。因此,包

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;

将产生这些类:

public class FAuthorExists1 { /* ... */ }
public class FAuthorExists2 { /* ... */ }

其他想法只会在代码生成时或运行时引起新的冲突。

更新:请注意,此解决方案似乎也是唯一正确处理此类情况的解决方案:

CREATE PACKAGE my_package IS
  PROCEDURE f_author_exists (name VARCHAR2);
  PROCEDURE f_author_exists (name CHAR);
  PROCEDURE f_author_exists (name CHAR, country OUT VARCHAR2);
END my_package;

看起来,这种重载在 PL/SQL 中也是可能的。

于 2010-12-19T22:59:29.430 回答
0

您可以通过为每个函数指定唯一名称来克服重载的限制。这也将提高代码的可读性(这也是Golang 没有重载的原因之一)。例如 f_author_name_exists、f_author_name_country_exists。

另一种使 Java 类复杂化的方法是在运行时根据使用的重载 Java 构造函数或使用的 setter 来决定调用哪个过程。

于 2012-05-11T06:54:39.933 回答