Objectifs du chapitre
- Créer un projet Spring Boot avec Maven.
- Comprendre la structure d’un projet Maven.
- Maîtriser la stack de persistance : JDBC, ORM, JPA, Hibernate, Spring Data JPA.
- Créer une entité JPA avec les annotations essentielles.
- Utiliser Lombok pour éliminer le code boilerplate.
- Implémenter une entité avec une énumération.
1. Spring Boot : définition
Spring Boot est le projet phare du framework Spring : il simplifie la création et le démarrage de nouvelles applications Spring en réduisant drastiquement la configuration.
- Il diminue énormément le temps de développement et augmente la productivité.
- Il permet l’utilisation de conteneurs embarqués (Tomcat, Jetty…), aucun serveur externe n’est requis.
- Les configurations Spring sont réduites au minimum.
- Les plugins Spring Boot facilitent le développement et les tests via Maven et Gradle.
Avantages
| Avantage | Détail |
|---|---|
| Gestion des configurations | Centralise toute la configuration dans un seul fichier : le développeur se focalise sur le métier plutôt que sur la configuration. |
| Serveur embarqué | Fournit des serveurs HTTP intégrés (Tomcat, Jetty…). En lançant le projet, le jar du Tomcat se dézippe et se lance. Le packaging .war reste possible pour la compatibilité avec des serveurs existants. |
| Gestion des dépendances | Utilise des starters : une seule dépendance ramène toutes les dépendances nécessaires et gère automatiquement les versions compatibles, via le parent spring-boot-starter-parent. |
Les 4 starters utilisés pour le projet AutoLoc :
| Starter | Rôle |
|---|---|
| Spring Data JPA | Gérer la persistance des données et le mapping objet-relationnel avec MySQL. |
| MySQL Driver | Établir la connexion entre Spring Boot et la base de données MySQL. |
| Lombok | Éliminer le code boilerplate (getters, setters, constructeurs…). |
| Spring Web | Créer les API REST et exposer les endpoints de l’application. |
2. Maven : définition et POM.xml
Maven est un outil pour faciliter la construction de projets (build, dépendances…) et l’automatisation des différentes phases d’un projet (tests, packaging…).
Maven permet :
- la gestion des builds (compilation) ;
- la gestion des dépendances (
*.jar) via le fichier POM ; - le lancement des tests (unitaires, qualité de code…) ;
- la génération des livrables.
Ce qui revient à automatiser les tâches récurrentes, donc à l’intégration continue (DevOps). Deux modes d’installation existent : standalone (utilisé en CI/CD) et plugin (intégré par défaut dans IntelliJ IDEA).
Le fichier pom.xml (POM, Project Object Model) est le fichier de configuration central de tout projet Maven. Il décrit le projet, ses dépendances, ses plugins et les étapes de construction, et spécifie l’emplacement de l’artefact du projet (groupId, artifactId, version).
Cycle de vie Maven
Maven définit un cycle de vie standardisé composé de phases exécutées dans l’ordre :
| Phase | Commande | Rôle |
|---|---|---|
| Compilation | mvn compile | Compile les fichiers .java en .class. |
| Tests | mvn test | Exécute les tests unitaires. |
| Packaging | mvn package | Génère le livrable dans /target. |
| Installation | mvn install | Copie le livrable dans le repo local ~/.m2. |
| Déploiement | mvn deploy | Envoie le livrable vers le repo distant. |
| Nettoyage | mvn clean | Supprime le dossier /target. |
Dépôts Maven
Les dépendances et starters sont téléchargés depuis un repository distant (Maven Central, accessible via https://mvnrepository.com/) puis mis en cache dans un repository local (~/.m2/repository). Maven vérifie d’abord le local avant de contacter le distant. Les dépôts sont organisés en groupes, artefacts et versions. Un dépôt distant peut aussi être interne (privé), hébergé dans les serveurs dédiés à l’entreprise pour des raisons de sécurité.
Arborescence du projet
Maven repose sur la convention over configuration : l’arborescence du projet est prédéfinie, ce qui le différencie de ses concurrents (Gradle, Ant) où une configuration supplémentaire est requise.
| Élément | Contenu |
|---|---|
pom.xml | Le fichier de configuration du projet. |
/src | Code source et fichiers source principaux. |
/src/main/java | Code source Java. |
/src/main/resources | Fichiers de ressources (images, fichiers de config, HTML…). |
/src/main/webapp | Webapp du projet. |
/src/test | Fichiers de test. |
/src/test/java | Code source Java de test. |
/src/test/resources | Fichiers de ressources de test. |
/target | Fichiers résultat : binaires du code et des tests, packages générés, résultats des tests. |
3. Persistance et ORM
Le problème de départ : le modèle relationnel (les SGBDR, incontournables en développement d’applications) et le modèle objet (programmation orientée objet, qualité et flexibilité) ne communiquent pas nativement. Comment stocker les objets modélisés de la mémoire vers les SGBDR ? On parle de persistance d’objets métiers.
Deux solutions :
- Développer manuellement le code de projection des objets sur le support relationnel (JDBC natif).
- Utiliser un framework de projection objet-relationnel (ORM) : EclipseLink, Hibernate, Spring Data JPA… qui implémentent la spécification Jakarta EE JPA.
La stack de persistance
| Couche | Classe / interface représentative | Rôle |
|---|---|---|
| Application | User.java, UserRepository.java | Code métier de l’application : entités et repositories. |
| Spring Data JPA | CrudRepository, JpaRepository | Simplifie l’accès aux données, sous-projet de Spring Data. |
| JPA | jakarta.persistence.EntityManager | Spécification Jakarta EE : une interface, pas une implémentation. |
| Hibernate | org.hibernate.Session | Implémentation concrète de JPA, framework ORM maintenu par RedHat/JBoss. |
| JDBC | javax.sql.PreparedStatement | API Java bas niveau, connexion directe à la base de données. |
| Base de données relationnelle |
JDBC : définition et limites
JDBC (Java DataBase Connectivity) est une interface de programmation créée par Sun Microsystems (racheté par Oracle), une API pour les programmes utilisant la plateforme Java.
- Permet aux applications Java d’accéder à des bases de données via des pilotes JDBC (drivers), disponibles pour tous les SGBDR connus.
- Pas de séparation entre le code technique et le code métier.
- L’utilisation du SQL rend la couche d’accès aux données difficilement maintenable.
- Code verbeux et répétitif.
ORM et JPA
Le mapping objet-relationnel (ORM) est une technique de programmation qui permet d’associer une ou plusieurs classes avec une table, et chaque attribut de la classe avec un champ de la table. Elle vise à réduire la quantité de code produit par l’API JDBC, les opérations restant les mêmes : connexion, CRUD, déconnexion.
La Jakarta Persistence API (JPA, anciennement Java Persistence API) est une interface de programmation Java permettant de normaliser l’utilisation et la communication avec la couche de données d’une application Java.
JPA nécessite un fournisseur de persistance (ORM) qui implémente ses spécifications (Hibernate, Toplink…) : JPA est une spécification (normalisation et standardisation), Hibernate est un produit (implémentation de cette spécification).
Hibernate et Spring Data JPA
Hibernate est un framework open source gérant la persistance des objets en base de données relationnelle. Il gère le mapping entre les objets de l’application et la base de données.
- Projet maintenu par JBoss, appartenant à RedHat.
- Génération automatique du code SQL (CRUD).
- Génération automatique des tables à partir des entités Java.
Spring Data est un module Spring (Pivotal) qui a pour but de faciliter l’écriture des couches d’accès aux données et d’offrir une abstraction commune pour l’accès aux données, quelle que soit la source (SQL ou NoSQL). Spring Data JPA est un sous-projet de Spring Data : il se base sur Hibernate comme implémentation de la spécification JPA. Plus besoin d’écrire les requêtes SQL basiques, grâce à des interfaces prêtes à l’emploi : CrudRepository, JpaRepository, PagingAndSortingRepository.
// 1. l'interface qui contient toutes les requêtes associées à l'entité
public interface ProjetDetailRepository extends JpaRepository<ProjetDetail, Long> {
}
// 2. le service qui consomme les requêtes du repository et contient la logique métier
@Service
@AllArgsConstructor
public class ProjetDetailService {
private ProjetDetailRepository projetDetailRepository;
public void addEtudiant(ProjetDetail projetDetail) {
projetDetailRepository.save(projetDetail);
}
}
4. Entité JPA et annotations
Une entité est une classe dont les instances peuvent être persistantes. Elle est déclarée avec l’annotation @Entity et possède au moins une propriété déclarée comme identité avec @Id.
| Annotation | Portée | Rôle |
|---|---|---|
@Entity | Classe (obligatoire) | Déclare la classe comme persistante et associée à une table. |
@Table(name="nomTable") | Classe (optionnel) | Redéfinit le nom de la table ; si omis, la table prend le nom de la classe. |
@Id | Attribut (obligatoire) | Déclare la clé primaire. |
@GeneratedValue(strategy=...) | Attribut (optionnel) | Définit la stratégie de génération de la clé primaire. |
@Column(name="...") | Attribut (optionnel) | Redéfinit le nom de la colonne. |
@Enumerated(EnumType.STRING) | Attribut | Pour les attributs de type Enum, stocke la valeur en String. |
Stratégies de @GeneratedValue :
| Stratégie | Effet |
|---|---|
AUTO | Géré par Hibernate (séquence globale). |
IDENTITY | AUTO_INCREMENT, Hibernate s’appuie sur le mécanisme propre au SGBD pour produire l’identifiant. |
SEQUENCE | Séquence définie manuellement. |
TABLE | Table dédiée aux séquences. |
Exemple, l’entité Livreur :
@Entity
@Table(name = "livreur")
@Getter @Setter @NoArgsConstructor @AllArgsConstructor
public class Livreur {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long idLivreur;
private String nom;
private String prenom;
private String telephone;
@Enumerated(EnumType.STRING)
private StatutLivreur statut;
}
5. Lombok avec Spring Boot
Lombok est une bibliothèque Java qui génère du code en respectant de nombreuses bonnes pratiques. Elle remplace le code répétitif (boilerplate) par des annotations faciles à utiliser : getters, setters, constructeurs, equals, hashCode, toString.
Sans Lombok, une entité ProjetDetail doit écrire à la main ses getters, setters, constructeurs, equals, hashCode et toString. Avec Lombok, les mêmes comportements tiennent dans les annotations de la classe :
@Entity
@Table(name = "projets_detail")
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder @ToString
@EqualsAndHashCode
public class ProjetDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String description;
private String technologie;
private Double coutProvisoire;
private LocalDate dateDebut;
}
6. Configuration : application.properties
Spring Boot centralise toute la configuration dans un seul fichier application.properties. Propriétés essentielles pour connecter l’application AutoLoc à MySQL :
spring.application.name=ProjetSpring
# Datasource MySQL
# URL de connexion à la BDD MySQL :
spring.datasource.url=jdbc:mysql://localhost:3306/ProjetSpring?createDatabaseIfNotExist=true
# Nom d'utilisateur MySQL
spring.datasource.username=root
# Mot de passe MySQL
spring.datasource.password=
# JPA / Hibernate
# Affiche les requêtes SQL générées en console
spring.jpa.show-sql=true
# Stratégie de génération des tables : update
spring.jpa.hibernate.ddl-auto=update
7. TP : étude de cas AutoLoc
Création de la première entité JPA du projet AutoLoc : l’entité Paiement, avec l’énumération ModePaiement, en vérifiant la création automatique de la table correspondante en base de données.