2015年2月25日水曜日

JPA2.1でストアドプロシージャ実行

JPA2.1のストアドプロシージャの実行機能の使い方サンプル。

実行対象のプロシージャ

INパラメータを2つ受け取って、その値の合計値をアウトパラメータで返却する単純なプロシージャです。
CREATE OR REPLACE FUNCTION PUBLIC.test_function(X INT, Y INT, RET OUT INT)
AS
$BODY$
BEGIN
  RET = Y + X;
END;
$BODY$
LANGUAGE plpgsql

実行例

EntityManagercreateStoredProcedureQueryにストアドプロシージャ名を指定してStoredProcedureQueryを生成します。
StoredProcedureQueryregisterStoredProcedureParameterを使用して、パラメータ情報を設定します。(パラメータの位置、イン or アウトパラメータや型情報を設定します。)
入力パラメータの場合には、setParameterを呼び出してストアドプロシージャに引き渡す値を設定します。

実行準備が整ったら、executeでストアドプロシージャを実行します。アウトパラメータはgetOutputParameterValueを使用して取得します。

CallableStatementと使い方は近いので特に迷うこともなさそうな気がします。
final StoredProcedureQuery storedProcedureQuery = em.createStoredProcedureQuery("test_function")
        .registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
        .setParameter(1, 10)
        .registerStoredProcedureParameter(2, Integer.class, ParameterMode.IN)
        .setParameter(2, 20)
        .registerStoredProcedureParameter(3, Integer.class, ParameterMode.OUT);
storedProcedureQuery.execute();
System.out.println("result = " + storedProcedureQuery.getOutputParameterValue(3));

NamedStoredProcedureQueryを使った場合の実行例


Entity側の準備

Entityには以下のように名前付きでストアドプロシージャの情報を定義します。
上の例で示したregisterStoredProcedureParameterの呼び出し部が、NamedStoredProcedureQueryparameters属性に設定されているイメージになります。
@NamedStoredProcedureQuery(
        name = "calc",
        procedureName = "test_function",
        parameters = {
                @StoredProcedureParameter(name = "x", type = Integer.class, mode = ParameterMode.IN),
                @StoredProcedureParameter(name = "y", type = Integer.class, mode = ParameterMode.IN),
                @StoredProcedureParameter(name = "result", type = Integer.class, mode = ParameterMode.OUT)
        })

実行分

createNamedStoredProcedureQueryにEntityで定義したストアドプロシージャクエリの名前を指定して、Queryを生成します。
生成した、Queryに対してパラメータ情報を設定して、executeを呼び出しアウトパラメータがある場合には結果を取得します。
上の例と比べると、パラメータの情報の設定がEntity側で定義されているのでなくなっています。
final StoredProcedureQuery func = em.createNamedStoredProcedureQuery("calc")
        .setParameter("x",1)
        .setParameter("y",2);
func.execute();
System.out.println("func.getOutputParameterValue(\"result\") = "+func.getOutputParameterValue(3));