Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle包和Java包之间的映射_Java_Stored Procedures_Code Generation_Packages_Jooq - Fatal编程技术网

Oracle包和Java包之间的映射

Oracle包和Java包之间的映射,java,stored-procedures,code-generation,packages,jooq,Java,Stored Procedures,Code Generation,Packages,Jooq,在我的数据库接口库中,我想添加对Oracle(或DB2等)包的支持。我已经实现了存储过程/函数支持,其中每个存储对象都被建模为生成的Java类。例如,此存储函数 CREATE FUNCTION f_author_exists (author_name VARCHAR2) RETURNS NUMBER; 将生成一个可以像这样使用的类(注意,还有很多方便的方法,本例仅显示了一般设计): 我之所以选择映射SQL函数->Java类,是因为存储过程允许复杂的返回值(几个OUT或IN-OUT参数),我希望

在我的数据库接口库中,我想添加对Oracle(或DB2等)包的支持。我已经实现了存储过程/函数支持,其中每个存储对象都被建模为生成的Java类。例如,此存储函数

CREATE FUNCTION f_author_exists (author_name VARCHAR2) RETURNS NUMBER;
将生成一个可以像这样使用的类(注意,还有很多方便的方法,本例仅显示了一般设计):

我之所以选择映射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;
当我为每个函数(或过程)生成一个类时,我将与几个
Java类发生命名冲突。一个蹩脚的解决方案是向类名添加索引,例如
FAuthorExists2
FAuthorExists3
。另一个蹩脚的解决方案是从参数名/类型直接生成某种散列值(或值本身)到类名,例如
FAuthorExistsVARCHAR2
FAuthorExistsVARCHAR2
。由于明显的原因,这两种解决方案都不可取

有人能简单地解决这个问题吗?或者是一个更好的整体设计的想法,它不会产生这样的函数名重载问题


任何反馈感谢

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

这样的方法,它最终会变得更简单在生成的类上使用“重载索引”比使用“重载索引”更困难。因此,一揽子计划

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中也是可能的。

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


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

实际调用的是
execute()
方法。该方法被称为
setName()
,因为函数参数
name
。我在示例中修正了这一点,使其更加清晰。你的主意不错。尽管如此,问题是如果函数名重载具有非常不同的参数集,那么找出可能的参数组合可能会让人困惑。但使用方便的方法,这实际上可能会起作用+1了解如何在运行时确定正确的调用-time@Lukas我的建议是在参数类型而不是名称上进行匹配——我认为这可能更简单。不过,我认为原则上这两种方法都是可能的。在如何基于参数名/类型/位置调用函数方面,很容易找到一个好的实现。但困难的部分是使生成的代码易于开发人员使用。这就是为什么我在生成的方法中使用参数的名称感谢您的提示。如问题中所述,这是一个为存储过程生成源代码的实用程序,因此我无法控制过程名重载—我一点也不介意。在创建方便的方法时,它增加了API的表达能力。另一方面,由于存在
OUT
参数,如果在代码生成时调用不是硬连接的,则很难决定在运行时调用哪个过程。。。
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;