it-swarm.com.de

Wie können wir eine gespeicherte Prozedur mit Hibernate und JPA aufrufen?

Wie können wir eine gespeicherte Prozedur mit Hibernate oder JPA aufrufen?

16
kandarp

Sie können Folgendes tun

 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();

Fügen Sie bei Bedarf die Ausnahmebehandlung hinzu. 

2

In Anbetracht der folgenden gespeicherten Prozedur, die einfach einen grundlegenden Rückgabewert zurückgibt:

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;

Sie können diese mit Standard-JPA aufrufen:

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);

Wenn die gespeicherte Prozedur einen SYS_REFCURSOR zurückgibt:

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;

Man kann es so nennen:

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();

Wenn Sie eine Oracle-Datenbankfunktion aufrufen möchten:

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;

Sie können die StoredProcedureQuery nicht verwenden, da sie mit Hibernate 5 nicht funktioniert. Sie können sie also wie folgt aufrufen:

BigDecimal commentCount = (BigDecimal) entityManager
    .createNativeQuery(
        "SELECT fn_count_comments(:postId) FROM DUAL"
    )
    .setParameter("postId", 1L)
    .getSingleResult();

oder mit einfacher 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 );
    }
} );

Weitere Informationen finden Sie in den folgenden Artikeln:

12
Vlad Mihalcea

Um eine Remoteprozedur auszuführen, verwenden Sie diese Konstruktion:

Kartierung

<sql-query name="RP">   
    {call some_rp(:param1, :param2)}
</sql-query>

Java-Code

session.getNamedQuery("RP").setInteger("param1", 1).setInteger("param2", 2).executeUpdate();
2
Mikhail.Mamaev
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
1
SandeepJain

Sie sollten zur offiziellen Website für den Winterschlaf gehen. Jedenfalls ist hier der Link , der Sie direkt zum Abschnitt für gespeicherte Prozeduren führt

0

ein Ansatz kann mit getNamedQuery () sein.

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());
}

sie müssen kartieren oder Anmerkungen verwenden

es gibt andere: source

0
demian

Hier ist die vollständige Lösung, um eine gespeicherte Prozedur mit Just IN-Parametern aufzurufen. ---

1) Erstellen Sie die gespeicherte Prozedur, um auf eine Tabelle oder einen Satz von Tabellen zu reagieren:

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) Führen Sie die gespeicherte Prozedur über die SQL-Eingabeaufforderung aus, um die Eingabe zu überprüfen. Wenn Sie die Prozedur auch von Java/Hibernate aus aufrufen, sollten Sie ein ähnliches Ergebnis sehen:

exec insertHouseHello(sysdate,'one',123,104); 

3) Im Java-Code:

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) Überprüfen Sie nun das Ergebnis in der Tabelle, das entsprechend aktualisiert werden sollte:

0
kanaparthikiran

Der Ruhezustand unterstützt Abfragen über gespeicherte Prozeduren und Funktionen. Sagen wir zum Beispiel, wenn wir die folgende gespeicherte Prozedur haben:

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;

Welches die Liste aller Mitarbeiter zurückgibt. Die gespeicherte Prozedur/Funktion muss ein Resultset als ersten Out-Parameter zurückgeben, um mit Hibernate arbeiten zu können. 

Um die obige Abfrage im Ruhezustand verwenden zu können, müssen Sie sie über eine benannte Abfrage zuordnen.

<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>

Regeln/Einschränkungen für die Verwendung gespeicherter Prozeduren:

  • Gespeicherte Prozedurabfragen können nicht mit setFirstResult ()/setMaxResults () gepaging werden.
  • Das empfohlene Aufrufformular ist Standard SQL92: { ? = call functionName(<parameters>) } oder { ? = call procedureName(<parameters>}. Die native Aufrufsyntax wird nicht unterstützt.

For Oracle the following rules apply:

  • Eine Funktion muss eine Ergebnismenge zurückgeben. 
  • Der erste Parameter einer Prozedur muss ein OUT sein, der eine Ergebnismenge zurückgibt. Dazu verwenden Sie in Oracle 9 oder 10 einen SYS_REFCURSOR-Typ. In Oracle müssen Sie einen REF CURSOR-Typ definieren. Weitere Informationen finden Sie in der Oracle-Dokumentation.

For Sybase or MS SQL server the following rules apply:

  • Die Prozedur muss eine Ergebnismenge zurückgeben. Da diese Server mehrere Ergebnismengen zurückgeben und die Anzahl der Aktualisierungen aktualisieren können, durchläuft Hibernate die Ergebnisse und verwendet das erste Ergebnis, das eine Ergebnismenge ist, als Rückgabewert. Alles andere wird verworfen.
  • Wenn Sie SET NOCOUNT ON in Ihrer Prozedur aktivieren können, ist dies wahrscheinlich effizienter. Dies ist jedoch keine Voraussetzung.

Source Ref .: Aus der offiziellen Dokumentation zum Hibernate.

0
Lucky