Partie back de l’application
Introduction
Ce chapitre aborde la gestion de données dans les applications utilisant des bases de données SQL. Un chapitre ultérieur se concentrera sur l’utilisation de bases de données NoSQL. Les bases de données SQL sont généralement choisies pour des applications ayant un historique avec ce type de base de données ou pour des applications peu susceptibles d’évoluer. La complexité accrue des applications utilisant des bases de données relationnelles est parfois considérée en regard de l’adoption de bases de données NoSQL, plus flexibles.
Les bases de données relationnelles, telles que MySQL, Oracle, Sybase, DB2, entre autres, organisent les données dans des structures tabulaires, ce qui signifie que les informations sont stockées dans des tables composées de lignes et de colonnes. Cependant, cette approche tabulaire n’est pas idéale pour gérer des données qui suivent un modèle basé sur des objets, typique dans la programmation orientée objet. Pour résoudre ce décalage entre la structure des bases de données relationnelles et les besoins de stockage des applications orientées objet, on fait souvent appel aux systèmes de gestion d’objets-relationnels (ORM). Les ORM permettent de mapper les entités de la programmation orientée objet...
Éléments fondamentaux
1. Stratégies d’héritage
Faire correspondre un modèle objet, qui supporte naturellement l’héritage et le polymorphisme, à un modèle relationnel plat basé sur des tables, représente un défi.
Hibernate est un framework populaire pour la gestion d’objets-relationnels (ORM) en Java qui offre plusieurs stratégies pour mapper des objets dans une application orientée objet sur des tables dans une base de données relationnelle. Voici un aperçu de ces quatre approches.
a. Objet par table
Cette approche consiste à mapper chaque classe d’entité sur une table distincte dans la base de données. Chaque champ (ou propriété) de l’objet est mappé sur une colonne correspondante dans la table. C’est la forme la plus courante et la plus directe de mappage ORM, offrant une correspondance claire entre l’objet dans l’application et sa représentation dans la base de données.
b. Table par hiérarchie de classe
Dans cette approche, une seule table est utilisée pour toute une hiérarchie de classes. Cela signifie que toutes les classes dans une hiérarchie d’héritage sont mappées sur une seule table. Des colonnes supplémentaires sont utilisées pour différencier les types d’objets et gérer les spécificités...
Mise en œuvre
La programmation des applications qui utilisent une base de données relationnelle avec du SQL s’est historiquement basée sur des fichiers de configuration XML et plus récemment via des annotations et des conventions de nommage.
1. Modèle en couche
Nous raisonnons en couches au niveau de la programmation classique avec Spring :
-
couche de présentation : généralement des contrôleurs ;
-
métier : généralement des services ;
-
DAO (Repository) : généralement des repositories ;
-
base de données : généralement des entités de domaines.
JPA 2 apporte des nouveautés qui n’étaient disponibles auparavant que dans Hibernate, comme la gestion de collections d’éléments avec l’annotation @ElementCollection, la suppression des orphelins (orphan removal), l’utilisation des requêtes typées, un cache de niveau 2 (L2), des liens avec l’API Bean Validation (JSR-303) et l’API Criteria que nous verrons par la suite.
2. Configuration d’une entité de la couche domaine
Par exemple, pour configurer une entité simple de la couche domaine nous utilisons un ensemble d’annotations comme :
@Entity
@Table(name = "table_book")
public class Livre implements Serializable {
@Id
@Column(name = "id")
private String auteur;
private int nbPage;
private String titre;
// getters et setters
[...]
}
Cet exemple ne montre que des API et des annotations JPA, car c’est un cas simple :
Élément |
Signification |
|
@Entity |
Indique qu’il s’agit d’une entité POJO. |
|
@Table(name = "table_book") |
Indique le nom de la table. |
|
@Id |
Indique que le champ sera une clé primaire. |
|
@Column(name = "id") |
Indique le nom de la colonne. |
|
private String auteur |
Donnée métier |
L’auteur du livre |
private int nbPage |
Donnée métier |
Le nombre de pages |
private String titre |
Donnée métier |
Le titre |
Il n’y a pas d’annotation sur les données métier, car il s’agit d’un type qu’Hibernate mappe sans difficulté au niveau...
Pour aller plus loin
Il existe des frameworks qui simplifient grandement la programmation Spring pour la partie base de données.
Utilisation de Liquibase
Liquibase est un outil open source de gestion de versions pour les schémas de bases de données. Il permet de suivre, de versionner et d’appliquer des changements au schéma de la base de données de manière contrôlée et automatisée. Liquibase utilise un format de fichiers déclaratifs (XML, YAML, JSON, ou SQL) pour décrire les changements nécessaires, facilitant ainsi le suivi des modifications, la synchronisation entre différents environnements, et la collaboration au sein des équipes de développement. C’est un outil très utile pour les projets nécessitant une gestion rigoureuse et évolutive de la structure de leurs bases de données.
Points clés
Points à retenir :
-
Les objets de la couche métier sont des objets de type Entity gérés par un EntityManager.
-
Les objets sont parfois disponibles sous forme de proxy.
-
JPA propose l’utilisation de plusieurs niveaux de caches.
-
Nous pouvons avoir des types personnalisés.
-
Nous améliorerons la maintenabilité de l’application en respectant le principe des couches applicatives.