Procédures stockées avec Hibernate

Procédures stockées avec Hibernate

1. Vue d'ensemble

Les procédures stockées sont des ensembles d'instructions SQL compiléesresiding in the database.. Elles sont utilisées 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 utiliserHibernate pour appeler unstored procedure dans unMySQL database.

2. Procédures stockées dans MySQL

Avant de discuter de la procédure à suivre pour appeler une procédure stockée à partir d’Hibernate, nous devons la créer.

Pour cet exemple rapide de MySQL, nous allonscreate a stored procedure pour récupérer tous les enregistrements d'une tablefoo.

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

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

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

Nous pouvons utiliser l'instructionCALL 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, voyons directement comment l'appeler depuis Hibernate.

3. Appeler une procédure stockée avec Hibernate

À partir de Hibernate 3, nous avons la possibilité d’utiliser des instructions SQL brutes, y compris 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édureGetAllFoos() en utilisant Hibernate.

3.1. Configuration

Avant de commencer à écrire du code capable de fonctionner, 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 deSessionFactory - vous pouvez consulter lesHibernate article.

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

Hibernate permet d'exprimer directement les requêtes au formatnative SQL. Par conséquent, nous pouvons directement créer une requête SQL native et utiliser l'instructionCALL pour appeler la procédure stockéegetAllFoos():

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 sbjectFoo o.

Nous utilisons la méthodeaddEntity() pour obtenir des objets d'entité à partir de la requête nativeSQL, sinon, unClassCastException sera lancé chaque fois qu'une procédure stockée retourne une valeur non brute.

3.3. Appel d'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 de requêtes nomméesSQL nativesscoped to the persistence unit:

@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 attributname, leSQL query réel et leresultClass qui fait référence à l'entité mappéeFoo.

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

L'attributresultClass joue le même rôle que la méthodeaddEntity() 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. Appel d'une procédure stockée à l'aide de@NamedStoredProcedureQuery

Si vous utilisezJPA 2.1 et l'implémentationHibernate desEntityManagerFactory etEntityManager.

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é unEntityManager,, puis appeler la méthodecreateNamedStoredProcedureQuery() pour créer la procédure:

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

Nous pouvons obtenir directement la liste des entitésFoo en appelant la méthodeexecute() sur l'objetStoredProcedureQuery.

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

Créons une procédure stockéegetFoosByName() dansMySQL.

Cette procédure retourne une liste d'objetsFoo où l'attribut name correspond au paramètrefooName:

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édureGetFoosByName(), 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");

Lors de l'utilisation de l'annotation@NamedStoredProcedureQuery, nous pouvons spécifier des paramètres en utilisant les@StoredProcedureParameter annotation:

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

Nous pouvons utiliser la méthoderegisterStoredProcedureParameter() pour appeler notre procédure stockée avec le paramètrefooName:

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

5. Conclusion

Cet article a démontréhow to use Hibernate to call a stored procedure in a MySQL database en utilisant différentes approches.

Il convient de mentionner quenot all RDBMS support stored procedures.

Vous pouvez consulter les exemples fournis dans cet article dans lesGitHub project liés.