Guide des procédures stockées avec JPA

1. Introduction

Dans ce rapide didacticiel, nous allons explorer l'utilisation des procédures stockées dans l'API Java Persistence (JPA).

2. Configuration du projet

2.1. Configuration de Maven

Nous devons d'abord définir les dépendances suivantes dans notre pom.xml :

  • javax.javaee-api - car il inclut l'API JPA
  • une implémentation d'API JPA - dans cet exemple, nous utiliserons Hibernate , mais EclipseLink serait également une alternative OK
  • une base de données MySQL
 7.0 11.2.0.4 5.1.38    javax javaee-api ${jee.version} provided   org.hibernate hibernate-core ${hibernate.version}   mysql mysql-connector-java ${mysql.version}  

2.2. Définition de l'unité de persistance

La deuxième étape est la création du fichier src / main / resources / META-INF / persistence.xml - qui contient les définitions des unités de persistance:

   org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.model.Car          

Toutes les propriétés Hibernate définies ne sont pas nécessaires si vous faites référence à une source de données JNDI (environnements JEE):

java:jboss/datasources/JpaStoredProcedure

2.3. Script de création de table

Créons maintenant une table (CAR) - avec trois attributs: ID, MODEL et YEAR :

CREATE TABLE `car` ( `ID` int(10) NOT NULL AUTO_INCREMENT, `MODEL` varchar(50) NOT NULL, `YEAR` int(4) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

L'hypothèse était, bien sûr, que le schéma de base de données et les autorisations étaient déjà en place.

2.4. Création de procédure stockée sur DB

La toute dernière étape avant de passer au code java est la création de la procédure stockée dans notre base de données MySQL:

DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `FIND_CAR_BY_YEAR`(in p_year int) begin SELECT ID, MODEL, YEAR FROM CAR WHERE YEAR = p_year; end $$ DELIMITER ;

3. La procédure stockée JPA

Nous sommes maintenant prêts à utiliser JPA pour communiquer avec la base de données et exécuter la procédure stockée que nous avons définie.

Une fois que nous aurons fait cela, nous pourrons également parcourir les résultats sous forme de liste de voitures.

3.1. L' entité automobile

Sous l' entité Car qui doit être mappée à la table de base de données CAR par le gestionnaire d'entités.

Notez que nous définissons également notre procédure stockée directement sur l'entité en utilisant l' annotation @NamedStoredProcedureQueries :

@Entity @Table(name = "CAR") @NamedStoredProcedureQueries({ @NamedStoredProcedureQuery( name = "findByYearProcedure", procedureName = "FIND_CAR_BY_YEAR", resultClasses = { Car.class }, parameters = { @StoredProcedureParameter( name = "p_year", type = Integer.class, mode = ParameterMode.IN) }) }) public class Car { private long id; private String model; private Integer year; public Car(String model, Integer year) { this.model = model; this.year = year; } public Car() { } @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID", unique = true, nullable = false, scale = 0) public long getId() { return id; } @Column(name = "MODEL") public String getModel() { return model; } @Column(name = "YEAR") public Integer getYear() { return year; } // standard setter methods }

3.2. Accéder à la base de données

Maintenant, avec tout défini et en place, écrivons quelques tests en utilisant réellement JPA pour exécuter la procédure.

Nous allons récupérer toutes les voitures dans une année donnée :

public class StoredProcedureTest { private static EntityManagerFactory factory = null; private static EntityManager entityManager = null; @BeforeClass public static void init() { factory = Persistence.createEntityManagerFactory("jpa-db"); entityManager = factory.createEntityManager(); } @Test public void findCarsByYearWithNamedStored() { StoredProcedureQuery findByYearProcedure = entityManager.createNamedStoredProcedureQuery("findByYearProcedure"); StoredProcedureQuery storedProcedure = findByYearProcedure.setParameter("p_year", 2015); storedProcedure.getResultList() .forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear())); } @Test public void findCarsByYearNoNamedStored() { StoredProcedureQuery storedProcedure = entityManager .createStoredProcedureQuery("FIND_CAR_BY_YEAR",Car.class) .registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN) .setParameter(1, 2015); storedProcedure.getResultList() .forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear())); } } 

Notez que dans le deuxième test, nous n'utilisons plus la procédure stockée que nous avons définie sur l'entité . Au lieu de cela, nous définissons la procédure à partir de zéro.

Cela peut être très utile lorsque vous devez utiliser des procédures stockées mais que vous n'avez pas la possibilité de modifier vos entités et de les recompiler.

4. Conclusion

Dans ce didacticiel, nous avons abordé l'utilisation de la procédure stockée avec l'API Java Persistence.

L'exemple utilisé dans cet article est disponible en tant qu'exemple de projet dans GitHub.