2010-12-14 5 views
6

데이터베이스 인터페이스 라이브러리 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 함수 ->자바 클래스 매핑을 선택한 이유는 저장 프로 시저가 프로 시저를 호출 한 후 하나씩 가져올 수있는 복잡한 반환 값 (여러 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 자바 클래스와 이름 충돌을 것 같은, 같은 이름으로 여러 기능을 가질 수있다 . 불완전한 솔루션은 FAuthorExists2, FAuthorExists3과 같은 클래스 이름에 인덱스를 추가하는 것입니다. 또 다른 절름발이 솔루션은 매개 변수 이름/유형에서 일종의 해시 값 (또는 값 자체)을 FAuthorExistsVARCHAR2, FAuthorExistsVARCHAR2VARCHAR2과 같은 클래스 이름으로 직접 생성하는 것입니다. 명백한 이유 때문에 어느 솔루션도 바람직하지 않습니다.

누구든지이 문제에 대한 간단한 해결책이 있습니까? 또는 함수 이름 오버로딩 문제를 일으키지 않는 더 나은 전체 디자인 아이디어일까요?

의견을 보내 주시면 감사하겠습니다.

답변

0

보다는 setParam1처럼 뭔가에 충실 경우 간단 끝나게 생각 생성 된 클래스에서 "오버로드 인덱스"를 사용하는 것보다이 문제를 해결할 다른 가능한 방법이 없습니다. 따라서, 패키지

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 { /* ... */ } 

다른 아이디어는 코드 생성시 새로운 갈등을 유발하거나 런타임에있다.

UPDATE :도 보인다으로

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에서 가능하다 : 참고,이 솔루션은 제대로 이와 같은 상황을 처리 할 수있는 단 하나 보인다.

3

얼마나 많은 입력 매개 변수를 설정 한에 따라 호출하는 기능을 오버로드 호출시에 결정할 수 귀하의 getReturnValue 기능 -하지만 난 당신이 setName

+0

'execute()'메소드는 실제 호출을합니다. 이 메소드는'name' 함수 인자 때문에'setName()'이라고 불립니다. 나는이 예에서 그것을 더 분명하게 고쳤다. 당신의 생각은 나쁜 것이 아닙니다. 매우 다른 인수 세트로 함수 이름이 오버로드되는 경우 문제점이 있지만 인수의 조합이 가능한지 알아내는 것은 혼란 스러울 수 있습니다. 그러나 편리한 방법으로, 실제로 작동 할 수도 있습니다! +1 런타임에서 정확한 호출을 결정하기위한 아이디어 –

+0

@Lukas는 이름이 아닌 인수 형식과 일치한다는 것이 내 제안에 의한 것이 었습니다. 더 간단 할 것이라고 생각했습니다. 나는 어느 쪽이든 원칙적으로 가능할 것이라고 생각한다. –

+0

인수 이름/유형/위치를 기반으로 함수를 호출하는 방법에 대한 좋은 구현을 쉽게 찾을 수 있습니다. 그러나 어려운 부분은 생성 된 코드를 개발자가 쉽게 사용할 수 있도록 만드는 것입니다. 그래서 생성 된 메소드에서 인수의 이름을 사용합니다. –

0

각 기능에 고유 한 이름을 지정하여 오버로드의 한계를 극복 할 수 있습니다.이렇게하면 코드의 가독성이 향상됩니다 (그 이유 중 하나는 why Golang doesn't have overloading입니다). 예를 들어, f_author_name_exists, f_author_name_country_exists.

Java 클래스를 복잡하게하는 또 다른 방법은 오버로드 된 Java 생성자를 사용했는지 또는 사용 된 설정자를 기반으로 호출 할 프로 시저를 런타임에 결정하는 것입니다.

+0

힌트를 보내 주셔서 감사합니다. 질문에서 언급했듯이 이것은 저장 프로 시저의 소스 코드를 생성하는 유틸리티 인 [jOOQ] (http://www.jooq.org)에 관한 것입니다. 따라서 프로 시저 이름 오버로딩을 제어 할 수 없습니다. 전혀 마음이 아프다. 편의 방법을 만들 때 API의 표현력을 향상시킵니다. 반면에 'OUT'매개 변수가 있기 때문에 런타임에 호출 할 프로 시저를 결정하는 것은 어렵습니다. 호출이 코드 생성 시간에 고정 배선되지 않은 경우 ... –

관련 문제