HibernateまたはJPAを使用してストアドプロシージャを呼び出すにはどうすればよいですか?
次のことができます
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
PreparedStatement st = session.connection().prepareStatement("{call procedureName(?, ?)}");
st.setString(1, formatter.format(parameter1));
st.setString(2, formatter.format(parameter2));
st.execute();
tx.commit();
必要に応じて例外処理を追加してください。
基本的な戻り値を返すだけの次のストアドプロシージャについて考えてみます。
CREATE OR REPLACE PROCEDURE count_comments (
postId IN NUMBER,
commentCount OUT NUMBER )
AS
BEGIN
SELECT COUNT(*) INTO commentCount
FROM post_comment
WHERE post_id = postId;
END;
これは標準のJPAで呼び出すことができます。
StoredProcedureQuery query = entityManager
.createStoredProcedureQuery("count_comments")
.registerStoredProcedureParameter(1, Long.class,
ParameterMode.IN)
.registerStoredProcedureParameter(2, Long.class,
ParameterMode.OUT)
.setParameter(1, 1L);
query.execute();
Long commentCount = (Long) query.getOutputParameterValue(2);
ストアドプロシージャがSYS_REFCURSORを返す場合:
CREATE OR REPLACE PROCEDURE post_comments (
postId IN NUMBER,
postComments OUT SYS_REFCURSOR )
AS
BEGIN
OPEN postComments FOR
SELECT *
FROM post_comment
WHERE post_id = postId;
END;
次のように呼び出すことができます。
StoredProcedureQuery query = entityManager
.createStoredProcedureQuery("post_comments")
.registerStoredProcedureParameter(1, Long.class,
ParameterMode.IN)
.registerStoredProcedureParameter(2, Class.class,
ParameterMode.REF_CURSOR)
.setParameter(1, 1L);
query.execute();
List<Object[]> postComments = query.getResultList();
Oracleデータベース関数を呼び出す場合:
CREATE OR REPLACE FUNCTION fn_count_comments (
postId IN NUMBER )
RETURN NUMBER
IS
commentCount NUMBER;
BEGIN
SELECT COUNT(*) INTO commentCount
FROM post_comment
WHERE post_id = postId;
RETURN( commentCount );
END;
StoredProcedureQuery
はHibernate 5では機能しないため使用できません。したがって、次のように呼び出すことができます。
BigDecimal commentCount = (BigDecimal) entityManager
.createNativeQuery(
"SELECT fn_count_comments(:postId) FROM DUAL"
)
.setParameter("postId", 1L)
.getSingleResult();
またはプレーンJDBCを使用:
Session session = entityManager.unwrap( Session.class );
Integer commentCount = session.doReturningWork( connection -> {
try (CallableStatement function = connection.prepareCall(
"{ ? = call fn_count_comments(?) }" )) {
function.registerOutParameter( 1, Types.INTEGER );
function.setInt( 2, 1 );
function.execute();
return function.getInt( 1 );
}
} );
詳細については、次の記事をご覧ください。
リモートプロシージャを実行するには、次の構文を使用します。
マッピング
<sql-query name="RP">
{call some_rp(:param1, :param2)}
</sql-query>
Javaコード
session.getNamedQuery("RP").setInteger("param1", 1).setInteger("param2", 2).executeUpdate();
One way to call the stored procedure from hibernate
Declare your store procedure inside the @NamedNativeQueries annotation
//Stock.Java
@NamedNativeQueries({
@NamedNativeQuery(
name = "callStockStoreProcedure",
query = "CALL GetStocks(:stockCode)",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock")
public class Stock implements Java.io.Serializable {
Call it with getNamedQuery().
Query query = session.getNamedQuery("callStockStoreProcedure")
.setParameter("stockCode", "7277");
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());
}
This works
Hibernateの公式ドキュメントサイトにアクセスする必要があります。とにかく リンクはこちら ストアドプロシージャセクションに直接移動します
1つの方法として、getNamedQuery()を使用できます。
Query query = session.getNamedQuery("callStockStoreProcedure")
.setParameter("stockCode", "7277");
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());
}
アノテーションをマッピングまたは使用する必要があります
他にあります: ソース
これは、INパラメータのみを指定してストアドプロシージャを呼び出すための完全なソリューションです---
1)テーブルまたはテーブルセットに作用するストアドプロシージャを作成します。
CREATE OR REPLACE procedure insertHouseHello (
house_date in timestamp,
house_name in varchar2,
house_number in number,
house_value in float)
is
begin
insert into House("HOUSE_DATE","HOUSE_NAME","HOUSE_NUMBER","HOUSE_VALUE")
values ( house_date, house_name,house_number,house_value);
commit;
end;
2)SQLプロンプトからストアドプロシージャを実行して、入力を確認します。 Java/Hibernateからプロシージャを呼び出すと、同様の結果が表示されます。
exec insertHouseHello(sysdate,'one',123,104);
3)Javaコード:
log.info("Now trying to call the Stored Procedure*****************");
Query exQuery = session.createSQLQuery("CALL " +
"insertHouseHello(:timestmp,:hname,:hno,:hvalue)");
exQuery.setParameter("timestmp",
new Java.sql.Timestamp(Calendar.getInstance().getTime().getTime()));
exQuery.setParameter("hname", 34);
exQuery.setParameter("hno", 212);
exQuery.setParameter("hvalue", 12);
int exRows = exQuery.executeUpdate();
log.info("Executed Rows from Stored Procedure****************"+exRows);
4)テーブルの結果を確認します。結果はそれに応じて更新されます。
Hibernateは、ストアドプロシージャと関数を介したクエリのサポートを提供します。たとえば、次のストアドプロシージャがあるとします。
_CREATE OR REPLACE FUNCTION selectAllEmployments
RETURN SYS_REFCURSOR
AS
st_cursor SYS_REFCURSOR;
BEGIN
OPEN st_cursor FOR
SELECT EMPLOYEE, EMPLOYER,
STARTDATE, ENDDATE,
REGIONCODE, EID, VALUE, CURRENCY
FROM EMPLOYMENT;
RETURN st_cursor;
END;
_
すべての従業員のリストを返します。ストアドプロシージャ/関数は、Hibernateで動作するための最初の出力パラメーターとして結果セットを返す必要があります。
上記のクエリをHibernateで使用するには、名前付きクエリを介してマップする必要があります。
_<sql-query name="selectAllEmployees_SP" callable="true">
<return alias="emp" class="Employment">
<return-property name="employee" column="EMPLOYEE"/>
<return-property name="employer" column="EMPLOYER"/>
<return-property name="startDate" column="STARTDATE"/>
<return-property name="endDate" column="ENDDATE"/>
<return-property name="regionCode" column="REGIONCODE"/>
<return-property name="id" column="EID"/>
<return-property name="salary">
<return-column name="VALUE"/>
<return-column name="CURRENCY"/>
</return-property>
</return>
{ ? = call selectAllEmployments() }
</sql-query>
_
ストアドプロシージャの使用に関する規則/制限:
{ ? = call functionName(<parameters>) }
または_{ ? = call procedureName(<parameters>}
_。ネイティブの呼び出し構文はサポートされていません。_For Oracle the following rules apply:
_
_For Sybase or MS SQL server the following rules apply:
_