OracleパッケージとJavaパッケージ間のマッピング
-
09-10-2019 - |
質問
私のデータベースインターフェイスライブラリで 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クラス ストアドプロシージャにより、複雑な戻り値(いくつかのアウト、またはアウトパラメーター)ができるためです。
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;
関数あたりのクラス(または手順)を生成すると、いくつかの衝突を命名します FAuthorExists
Javaクラス。足の不自由なソリューションは、クラス名にインデックスを追加することです。 FAuthorExists2
, FAuthorExists3
. 。別の不自由な解決策は、パラメーター名/タイプから何らかのハッシュ値(または値自体)をクラス名に直接生成することです。 FAuthorExistsVARCHAR2
, FAuthorExistsVARCHAR2VARCHAR2
. 。どちらのソリューションも明らかな理由で望ましくありません。
誰かがこの問題の簡単な解決策を持っていますか?それとも、そのような関数名の過負荷の問題を生成しないより良い全体的な設計のアイデアですか?
どんなフィードバックも感謝しています!
解決 2
生成されたクラスで「過負荷インデックス」を使用する以外に、この問題を解決する他の実行可能な方法は見つかりませんでした。したがって、パッケージ
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で可能です。
他のヒント
あなたの getReturnValue
関数は、コールタイムで、設定された入力パラメーターの数に応じて呼び出した過負荷関数を決定できますが、次のようなものに固執すると簡単になると思います。 setParam1
それよりも setName
各関数に一意の名前を与えることにより、オーバーロードの制限を克服できます。これにより、コードの読みやすさも向上します(それが1つの理由です Golangに過負荷がない理由)。たとえば、f_author_name_exists、f_author_name_country_exists。
Javaクラスを複雑にする別の方法は、実行時に、どの過負荷のJavaコンストラクターが使用されたか、どのセッターが使用されたかに基づいて、どの手順を呼び出すかを決定することです。