Comment appeler une procédure stockée à l'aide d'Hibernate ou de JPA?
Vous pouvez faire ce qui suit
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();
S'il vous plaît ajouter la gestion des exceptions, le cas échéant.
Considérant la procédure stockée suivante qui renvoie simplement une valeur de retour de base:
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;
Vous pouvez appeler celui-ci avec JPA standard:
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);
Si la procédure stockée retourne 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;
Vous pouvez l'appeler comme ça:
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();
Si vous souhaitez appeler une fonction de base de données 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;
Vous ne pouvez pas utiliser StoredProcedureQuery
car il ne fonctionne pas avec Hibernate 5, vous pouvez donc l'appeler ainsi:
BigDecimal commentCount = (BigDecimal) entityManager
.createNativeQuery(
"SELECT fn_count_comments(:postId) FROM DUAL"
)
.setParameter("postId", 1L)
.getSingleResult();
ou avec JDBC simple:
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 );
}
} );
Pour plus de détails, consultez les articles suivants:
Pour exécuter une procédure à distance, utilisez cette construction:
Cartographie
<sql-query name="RP">
{call some_rp(:param1, :param2)}
</sql-query>
Code 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
Vous auriez dû vous rendre sur le site officiel de documentation d'hibernation. Quoi qu'il en soit voici le lien qui vous emmène directement à la section procédure stockée
une approche peut être avec 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());
}
vous devez mapper ou utiliser des annotations
il y en a d'autres: source
Voici la solution complète pour appeler une procédure stockée avec les paramètres Just IN ---
1) Créez la procédure stockée pour agir sur une table ou un ensemble de tables:
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) Exécutez la procédure stockée à partir de l'invite SQL pour vérifier l'entrée. Lorsque vous appelez la procédure à partir de Java/Hibernate également, vous devriez voir le résultat similaire:
exec insertHouseHello(sysdate,'one',123,104);
3) Dans le code 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) Maintenant, vérifiez le résultat dans le tableau, cela devrait être mis à jour en conséquence:
Hibernate fournit un support pour les requêtes via des procédures et des fonctions stockées. Disons par exemple si nous avons la procédure stockée suivante,
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;
Ce qui retourne la liste de tous les employés. La procédure/fonction stockée doit renvoyer un jeu de résultats en tant que premier paramètre de sortie pour pouvoir fonctionner avec Hibernate.
Pour utiliser la requête ci-dessus dans Hibernate, vous devez la mapper via une requête nommée.
<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>
Règles/limitations d'utilisation des procédures stockées:
{ ? = call functionName(<parameters>) }
ou { ? = call procedureName(<parameters>}
. La syntaxe d'appel natif n'est pas prise en charge._ {For Oracle the following rules apply:
_ {For Sybase or MS SQL server the following rules apply:
Référence de la source: D'après la documentation officielle d'Hibernate.