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 パラメータ) を許可し、プロシージャを呼び出した後に 1 つずつ取得できるようにするためです。

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関数は、設定された入力パラメーターの数に応じて、呼び出すオーバーロードされた関数を呼び出し時に決定できますがsetParam1setName

于 2010-12-14T14:25:31.580 に答える
0

関数ごとに一意の名前を付けることで、オーバーロードの制限を克服できます。これにより、コードの可読性も向上します(これが、Golangにオーバーロードがない理由の1つです)。たとえば、f_author_name_exists、f_author_name_country_exists。

Javaクラスを複雑にする別の方法は、実行時に、どのオーバーロードされたJavaコンストラクターが使用されたか、またはどのセッターが使用されたかに基づいて、呼び出すプロシージャを決定することです。

于 2012-05-11T06:54:39.933 に答える
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 に答える