Procédures stockées avec Hibernate

1. Vue d'ensemble

Les procédures stockées sont des ensembles d'instructions SQL compilées résidant dans la base de données. Ils sont utilisés pour encapsuler et partager la logique avec d'autres programmes, et bénéficient de fonctionnalités spécifiques à la base de données telles que des indices d'index ou des mots-clés spécifiques.

Cet article montre comment utiliser Hibernate pour appeler une procédure stockée dans une base de données MySQL .

2. Procédures stockées dans MySQL

Avant de discuter de la manière d'appeler une procédure stockée à partir d'Hibernate, nous devons la créer.

Pour cet exemple rapide de MySQL, nous allons créer une procédure stockée pour obtenir tous les enregistrements d'une table foo .

Pour créer une procédure stockée, nous utilisons l' instruction CREATE PROCEDURE :

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

Avant l' instruction BEGIN , nous pouvons définir des instructions optionnelles. Vous pouvez explorer les détails de ces déclarations en suivant le lien officiel de la documentation MySQL.

Nous pouvons utiliser l' instruction CALL pour nous assurer que notre procédure se comporte de la manière souhaitée:

CALL GetAllFoos();

Maintenant que notre procédure stockée est opérationnelle, passons directement à la façon de l'appeler depuis Hibernate.

3. Appel d'une procédure stockée avec Hibernate

À partir d'Hibernate 3, nous avons la possibilité d'utiliser une instruction SQL brute comprenant des procédures stockées pour interroger une base de données.

Dans cette section, nous allons parcourir un exemple apparemment basique qui illustrera comment appeler la procédure GetAllFoos () en utilisant Hibernate.

3.1. Configuration

Avant de commencer à écrire du code qui peut s'exécuter, nous devons avoir configuré Hibernate dans notre projet.

Et bien sûr, pour tout cela - les dépendances Maven, la configuration MySQL, la configuration Hibernate et l' instanciation SessionFactory - vous pouvez consulter l'article Hibernate.

3.2. Appel d'une procédure stockée à l'aide de la méthode CreateNativeSQL

Hibernate permet d'exprimer directement des requêtes au format SQL natif . Par conséquent, nous pouvons directement créer une requête SQL native et utiliser l' instruction CALL pour appeler la procédure stockée getAllFoos () :

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

La requête ci-dessus renvoie une liste où chaque élément est un objet Foo o .

Nous utilisons la méthode addEntity () pour obtenir des objets d'entité à partir de la requête SQL native , sinon, une ClassCastException sera lancée chaque fois qu'une procédure stockée renvoie une valeur non brute.

3.3. Appeler une procédure stockée à l'aide de @NamedNativeQueries

Une autre façon d'appeler une procédure stockée consiste à utiliser l' annotation @NamedNativeQueries .

@NamedNativeQueries est utilisé pour spécifier un tableau derequêtes nommées SQL natives étendues à l'unité de persistance:

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

Chaque requête nommée a évidemment un attribut name , la requête SQL réelle et la resultClass qui fait référence à l' entité mappée Foo .

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

L' attribut resultClass joue le même rôle que la méthode addEntity () dans notre exemple précédent.

Ces deux approches peuvent être utilisées de manière interchangeable, car il n'y a pas de réelle différence entre les deux en termes de performances ou de productivité.

3.4. Appeler une procédure stockée à l'aide de @NamedStoredProcedureQuery

Si vous utilisez JPA 2.1 et l' implémentation Hibernate de EntityManagerFactory et EntityManager .

L' annotation @NamedStoredProcedureQuery peut être utilisée pour déclarer une procédure stockée:

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

Pour appeler notre requête de procédure stockée nommée, nous devons avoir instancié un EntityManager, puis appeler la méthode createNamedStoredProcedureQuery () pour créer la procédure :

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

Nous pouvons obtenir directement la liste des entités Foo en appelant la méthode execute () sur l' objet StoredProcedureQuery .

4. Procédures stockées avec paramètres

Presque toutes nos procédures stockées nécessiteront des paramètres. Dans cette section, nous allons montrer comment appeler une procédure stockée avec des paramètres d' Hibernate .

Créons une procédure stockée getFoosByName () dans MySQL .

Cette procédure renvoie une liste d' objets Foo où l'attribut name correspond au paramètre fooName :

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

Pour appeler la procédure GetFoosByName () , nous utiliserons des paramètres nommés:

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

De même, le paramètre nommé : fooName peut être utilisé avec l' annotation @NamedNativeQuery :

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

La requête nommée serait appelée comme suit:

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

Lorsque vous utilisez l' annotation @NamedStoredProcedureQuery , nous pouvons spécifier des paramètres à l'aide de l' annotation @StoredProcedureParameter :

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

Nous pouvons utiliser la méthode registerStoredProcedureParameter () pour appeler notre procédure stockée avec le paramètre fooName :

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

5. Conclusion

Cet article a montré comment utiliser Hibernate pour appeler une procédure stockée dans une base de données MySQL en utilisant différentes approches.

Il est à noter que tous les SGBDR ne prennent pas en charge les procédures stockées .

Vous pouvez consulter les exemples fournis dans cet article dans le projet GitHub lié.