Stored procedure con Hibernate

1. Panoramica

Le stored procedure sono set di istruzioni SQL compilate che risiedono nel database. Vengono utilizzati per incapsulare e condividere la logica con altri programmi e traggono vantaggio da funzionalità specifiche del database come suggerimenti di indice o parole chiave specifiche.

Questo articolo mostra come utilizzare Hibernate per chiamare una stored procedure in un database MySQL .

2. Procedure memorizzate in MySQL

Prima di discutere come chiamare una stored procedure da Hibernate, dobbiamo crearla.

Per questo rapido esempio di MySQL, creeremo una stored procedure per ottenere tutti i record da una tabella foo .

Per creare una stored procedure, utilizziamo l' istruzione CREATE PROCEDURE :

DELIMITER // CREATE PROCEDURE GetAllFoos() LANGUAGE SQL DETERMINISTIC SQL SECURITY DEFINER BEGIN SELECT * FROM foo; END // DELIMITER;

Prima dell'istruzione BEGIN , possiamo definire istruzioni opzionali. Puoi approfondire i dettagli di queste dichiarazioni seguendo il link ufficiale della documentazione di MySQL.

Possiamo usare l' istruzione CALL per assicurarci che la nostra procedura si comporti nel modo desiderato:

CALL GetAllFoos();

Ora che abbiamo la nostra stored procedure attiva e funzionante, passiamo direttamente a come chiamarla da Hibernate.

3. Chiamare una stored procedure con Hibernate

A partire da Hibernate 3, abbiamo la possibilità di utilizzare istruzioni SQL non elaborate comprese le stored procedure per interrogare un database.

In questa sezione, esamineremo un esempio apparentemente semplice che illustrerà come chiamare la procedura GetAllFoos () utilizzando Hibernate.

3.1. Configurazione

Prima di iniziare a scrivere codice che possa essere eseguito, dobbiamo aver configurato Hibernate nel nostro progetto.

E ovviamente per tutto ciò - le dipendenze di Maven, la configurazione di MySQL, la configurazione di Hibernate e l' istanza di SessionFactory - puoi controllare l'articolo di Hibernate.

3.2. Chiamare una stored procedure utilizzando il metodo CreateNativeSQL

Hibernate consente di esprimere direttamente le query in formato SQL nativo . Pertanto, possiamo creare direttamente una query SQL nativa e utilizzare l' istruzione CALL per chiamare la procedura memorizzata getAllFoos () :

Query query = session.createSQLQuery("CALL GetAllFoos()").addEntity(Foo.class); List allFoos = query.list(); 

La query precedente restituisce un elenco in cui ogni elemento è un oggetto Foo .

Utilizziamo il metodo addEntity () per ottenere oggetti entità dalla query SQL nativa , altrimenti verrà generata un'eccezione ClassCastException ogni volta che una procedura memorizzata restituisce un valore non grezzo.

3.3. Chiamare una stored procedure utilizzando @NamedNativeQueries

Un altro modo per chiamare una stored procedure consiste nell'usare l' annotazione @NamedNativeQueries .

@NamedNativeQueries viene utilizzato per specificare un array diquery con nome SQL native con ambito per l'unità di persistenza:

@NamedNativeQueries({ @NamedNativeQuery( name = "callGetAllFoos", query = "CALL GetAllFoos()", resultClass = Foo.class) }) @Entity public class Foo implements Serializable { // Model definition }

Ogni query denominata ha ovviamente un attributo name , la query SQL effettiva e la resultClass che si riferisce all'entità mappata Foo .

Query query = session.getNamedQuery("callGetAllFoos"); List allFoos = query.list();

L' attributo resultClass svolge lo stesso ruolo del metodo addEntity () nel nostro esempio precedente.

Entrambi questi approcci possono essere utilizzati in modo intercambiabile, poiché non ci sono differenze reali tra i due quando si tratta di prestazioni o produttività.

3.4. Chiamare una stored procedure utilizzando @NamedStoredProcedureQuery

Se stai usando JPA 2.1 e l' implementazione Hibernate di EntityManagerFactory e EntityManager .

L' annotazione @NamedStoredProcedureQuery può essere utilizzata per dichiarare una stored procedure:

@NamedStoredProcedureQuery( name="GetAllFoos", procedureName="GetAllFoos", resultClasses = { Foo.class } ) @Entity public class Foo implements Serializable { // Model Definition } 

Per chiamare la nostra query di stored procedure denominata, è necessario aver istanziato un EntityManager, quindi chiamare il metodo createNamedStoredProcedureQuery () per creare la procedura :

StoredProcedureQuery spQuery = entityManager.createNamedStoredProcedureQuery("getAllFoos"); 

Possiamo ottenere direttamente l'elenco delle entità Foo chiamando il metodo execute () sull'oggetto StoredProcedureQuery .

4. Stored procedure con parametri

Quasi tutte le nostre procedure memorizzate richiederanno parametri. In questa sezione, mostreremo come chiamare una stored procedure con parametri da Hibernate .

Creiamo una procedura memorizzata getFoosByName () in MySQL .

Questa procedura restituisce un elenco di oggetti Foo in cui l'attributo name corrisponde al parametro fooName :

DELIMITER // CREATE PROCEDURE GetFoosByName(IN fooName VARCHAR(255)) LANGUAGE SQL DETERMINISTIC SQL SECURITY DEFINER BEGIN SELECT * FROM foo WHERE name = fooName; END // DELIMITER;

Per chiamare la procedura GetFoosByName () useremo parametri denominati:

Query query = session.createSQLQuery("CALL GetFoosByName(:fooName)") .addEntity(Foo.class) .setParameter("fooName","New Foo");

Allo stesso modo, il parametro denominato : fooName può essere utilizzato con l' annotazione @NamedNativeQuery :

@NamedNativeQuery( name = "callGetFoosByName", query = "CALL GetFoosByName(:fooName)", resultClass = Foo.class )

La query denominata verrebbe chiamata come segue:

Query query = session.getNamedQuery("callGetFoosByName") .setParameter("fooName","New Foo");

Quando si utilizza l' annotazione @NamedStoredProcedureQuery , è possibile specificare i parametri utilizzando l' annotazione @StoredProcedureParameter :

@NamedStoredProcedureQuery( name="GetFoosByName", procedureName="GetFoosByName", resultClasses = { Foo.class }, parameters={ @StoredProcedureParameter(name="fooName", type=String.class, mode=ParameterMode.IN) } ) 

Possiamo fare uso del metodo registerStoredProcedureParameter () per chiamare la nostra stored procedure con il parametro fooName :

StoredProcedureQuery spQuery = entityManager. createNamedStoredProcedureQuery("GetFoosByName") .registerStoredProcedureParameter( "New Foo", String.class , ParameterMode.IN );

5. conclusione

Questo articolo ha dimostrato come utilizzare Hibernate per chiamare una stored procedure in un database MySQL utilizzando approcci diversi.

Vale la pena ricordare che non tutti gli RDBMS supportano le stored procedure .

Puoi controllare gli esempi forniti in questo articolo nel progetto GitHub collegato.