la couche persistance hibernate
DESCRIPTION
Hibernate est une solution open source de type ORM (Object Relational Mapping) qui permet de faciliter le développement de la couche persistance d'une application. Hibernate permet donc de représenter une base de données en objets Java et vice versa.TRANSCRIPT
MD
-3-0
1-S
M-1
0 ré
v. B1
La couche persistance
MD
-3-0
1-S
M-1
0 ré
v. B1
Le plan
• Introduction rappel architecture Java EE
• La couche de persistance
• Accès JDBC vers Base de Données
• Hibernate
MD
-3-0
1-S
M-1
0 ré
v. B1
Introduction: Principes J2EE
MD
-3-0
1-S
M-1
0 ré
v. B1
Le problème et la solution
MD
-3-0
1-S
M-1
0 ré
v. B1
Architecture en couche
MD
-3-0
1-S
M-1
0 ré
v. B1
Le schéma de conception DAO
• DAO = Data Access Object
• Résout la problématique d’isolation entre les couches Business et Persistance
• Permet d’exposer sous forme de service les accès vers les données
• Améliore la mise en œuvre des tests
MD
-3-0
1-S
M-1
0 ré
v. B1
UML d’un DAOc la s s DAO
IDA O
« i n te rfa ce ,d a o »
IC rudD AO
+ a j o u te r(IDa ta ) : vo id
+ ch a rg e r(IDa ta ) : IDa ta
+ sa u ve g a rd e r(IDa ta ) : vo id
+ su p p ri m e r(IDa ta ) : vo id
A b stra c tH ib e rn a te DA O
« d a o »
hibe rna te ::
Ba s ic CrudHibe rna te D AO
+ a j o u te r(IDa ta ) : vo id
+ ch a rg e r(IDa ta ) : IDa ta
+ f i n a l i ze () : vo i d
+ sa u ve g a rd e r(ID a ta ) : vo id
+ S i m p l e Cru d H i b e rn a te DA O ()
+ su p p ri m e r(IDa ta ) : vo id
« d a o »
Ba s ic CrudJ dbc DAO
+ a jo u te r(IDa ta ) : vo i d
+ ch a rg e r(ID a ta ) : ID a ta
+ sa u ve g a rd e r(IDa ta ) : vo i d
+ su p p rim e r(IDa ta ) : vo i d
« i n te rfa ce »
v a lue obje c t::IDa ta
+ to S tri n g () : S tri n g« u se »
MD
-3-0
1-S
M-1
0 ré
v. B1
Accès aux bases de données
MD
-3-0
1-S
M-1
0 ré
v. B1
Implémentation de type JDBC
• Accès via un driver à la base de données• Drivers JDBC (4 types de drivers)
• La marche à suivre pour l’implémentation
• Charger le driver correspondant au SGDB
• Obtenir une Connection
• Obtenir un Statement encapsulant une phrase SQL
• Obtenir un ResultSet encapsulant le résultat de la phrase SQL
• Exploiter le ResultSet
MD
-3-0
1-S
M-1
0 ré
v. B1
JDBC - La marche à suivre• Etablir une connexion
MD
-3-0
1-S
M-1
0 ré
v. B1
JDBC – La marche à suivre• Obtenir un Statement et exploitation des résultats
MD
-3-0
1-S
M-1
0 ré
v. B1
Les outils ORM
MD
-3-0
1-S
M-1
0 ré
v. B1
Autre solution• Une autre solution pour faire correspondre des objets avec
une base relationnelle sont les outils ORM (Object Relational Mapping)
• Qu’apporte un outil ORM
• Automatise ou facilite la correspondance entre des données stockées dans des objets et une base de données relationnelle
• Le plus souvent les données sont décrites dans des fichiers de configuration (souvent XML)
• Les principaux produits : TopLink d’Oracle(commercial) et Hibernate (open source)
MD
-3-0
1-S
M-1
0 ré
v. B1
Les outils ORM
• Fonctionnalités de base• Recherche et enregistre les données associées à un objet
dans une base de données
• Détecte quand un objet a été modifié et l’enregistre en optimisant les accès à la base
• Avantages• Évite l’écriture de code répétitif, inintéressant et source
d’erreurs difficiles à déceler
• Gain de 30 à 40 % du nombre de lignes de certains projets
• Améliore la portabilité du code pour des changements de SGBD
MD
-3-0
1-S
M-1
0 ré
v. B1
Les outils ORM
• Avantages
• Le développeur pense en termes d’objet et pas en termes de lignes de tables
• Sans outil ORM le développeur peut hésiter à concevoir un modèle objet « fin » afin d’éviter du codage complexe pour la persistance
• Le refactoring du schéma de la base de données ou du modèle objet est facilité
MD
-3-0
1-S
M-1
0 ré
v. B1
Les travers
• Ce type d’outil n’est pas adapté dans le cas de manipulation importante de lignes pour chaque update
• La manipulation d’un grand nombre d’objets nuit aux performances
MD
-3-0
1-S
M-1
0 ré
v. B1
Les classes de persistantes dans Hibernate• Ce sont de simple objet java (POJO : Plain Old Java
Objects)
• Pas d’implémentation d’interface ou d’héritage spécifique
• Contraintes obligatoires
MD
-3-0
1-S
M-1
0 ré
v. B1
Contraintes• Contraintes obligatoires pour les classes persistantes
• Elles doivent avoir un constructeur sans paramètre (il peut être privé, mais il est préférable qu’il soit accessible par le paquetage)
• Les collections qui représentent des associations doivent être typées avec des interfaces et non des classes ; par exemple Set et pas HashSet
• Contraintes optionnelles mais recommandées
• Un des champs doit identifier une instance parmi toutes les autres de la même classe
• Tous les champs qui sont persistants doivent avoir un modificateur (setter) et un accesseur (getter) ; ils peuvent être privés
MD
-3-0
1-S
M-1
0 ré
v. B1
Fichier de Mapping
• Décrit comment se fera la persistance des objets d’une classe
• Format XML ; grammaire imposée
• Se place dans le même répertoire que la classe et se nomme Classe.hbm.xml si la classe s’appelle Classe (facultatif)
MD
-3-0
1-S
M-1
0 ré
v. B1
Exemple de fichier de mapping
MD
-3-0
1-S
M-1
0 ré
v. B1
Attribut du tag property
• column indique le nom de la colonne dans la table relationnelle
• Par défaut, elle a le même nom que la propriété (attribut « name »)
• type indique le type « Hibernate » de la propriété ; Hibernate en déduit le type SQL et le type Java
• Par défaut, il est déterminé par introspection de la classe
MD
-3-0
1-S
M-1
0 ré
v. B1
Identificateur
• Le tag id est obligatoire pour chaque classe qui est représentée par une table (une classe « composant » n’est pas représentée par une table)
• Il indique quelle sera la clé primaire de la table
• Remarque : les sous-classes héritent des identificateurs de leur classe mère
MD
-3-0
1-S
M-1
0 ré
v. B1
Les états des objets
• Les actions en base sont reportées au niveau des objets mappés• Sauvegarde
• Lecture
• Mise à jour
MD
-3-0
1-S
M-1
0 ré
v. B1
Exemple d’utilisation
MD
-3-0
1-S
M-1
0 ré
v. B1
L’objet Java persistant
class Persistance
Ev ent
- date: Date
- id: Long
- ti tle: String
+ Event()
+ getDate() : Date
+ getId() : Long
+ getT itle() : String
+ setDate(Date) : void
- setId(Long) : void
+ setT itle(String) : void
MD
-3-0
1-S
M-1
0 ré
v. B1
Correspondance Objet-Relationnel
MD
-3-0
1-S
M-1
0 ré
v. B1
Etats d’une entité (objet mappé sur la BDD)
L’instance d’une entité possède 3 états possibles :
• Transient / Ephémère :• Non associé à un contexte de persistance
• Pas d'identifiant de persistance (valeur de clé primaire)
• Persistant :• Associé au contexte de persistance
• Possède un identifiant (ou associé à un objet qui possède un id.)
• Détaché :• Précédemment associé au contexte de persistance
• Contexte de persistance fermé
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de persistance : CRUD
• Create (Insertion)
• Read (Lecture)
• Update (Modification)
• Delete (Suppression)
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de création
• Création d’une nouvelle entité
Person aPerson = new Person();
session.save(aPerson);
• Création par association à une entité persistante
Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = new Event();
aPerson.addEvent(anEvent);
• Une session doit être ouverte
• L’identifiant du nouvel objet est affecté par Hibernate
• Attention aux contraintes de champ obligatoire
• Sauvegarde par « grappe » d’entités
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de modification
• Modification d’une entité persistante
Person aPerson = (Person) session.load(Person.class, personId);
aPerson.setPrenom("autre Prenom");
• Modification d’une entité détachée
aPerson.setPrenom("autre Prenom"); // en dehors de la session
session.update(aPerson); // rattachement de l’entité
• Modification via une association
Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = aPerson.getFirstEvent();
anEvent.setDate(new Date());
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de suppression
• Suppression d’une entité persistante
Person aPerson = (Person) session.load(Person.class, personId);
session.delete(aPerson);
• Suppression via une association
Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = aPerson.getEvents().removeFirst();
• Destruction des entités orphelines
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture
• Possibilités multiples :
• Recherche par l’identifiant
• Recherche par une association
• Recherche HQL (Hibernate Query Language)
• Recherche SQL
• Recherche par critère (QBC)
• Recherche par l’exemple (QBE)
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture (simple)
• Chargement d’une entité par l’identifiant
Person aPerson = (Person) session.load(Person.class, personId);
Person aPerson = new Person();
session.load(aPerson, personId);
• Chargement d’une entité via une association
Person aPerson = (Person) session.load(Person.class, personId);
Set<Event> events = aPerson.getEvents();
• Multiplication du nombre d’accès base de données !
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture (HQL)
• Chargement explicite entité + association
Person aPerson = (Person) session.createQuery("select p from Person p left join fetch p.events where p.id =
:pid").setParameter("pid", personId).uniqueResult();
• Utilisation du modèle métier (entités)
• Chargement avec critères (clause where)
• Un seul accès base de données (mot clé fetch)
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture (Criteria)
• Recherche multi-critères sur une entité
Criteria crit = session.createCriteria(Person.class);
crit.add( Expression.eq( "nom", "PIGNON" ) );
crit.add( Expression.like( "prenom", "R%" ) );
List<Person> persons = crit.list();
• Combiner les expressions• Comparaisons unitaires
• Comparaisons sur des fonctions de groupes
• Opérations logiques entre expressions
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture (Criteria)
• Palette d’expressions très large :
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture (Query By Example)
• Recherche par l’exemple sur une entité
Person exemple = new Person();
Exemple.setNom("PIGNON");
Exemple.setPrenom("R%");
List<Person> persons = session.createCriteria(Person.class)
.add( Example.create(exemple).enableLike() )
.list();
• Simplicité d’utilisation
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture (SQL natif)
• Recherche en SQL natif sur une entité
String requete =
"SELECT count(*) FROM TCSFDOSSIERCONTROLESURFACE dossier " +
"WHERE exists (SELECT 1 " +
"FROM TCSFSELECTIONDOSSIERCTRL selection, " +
"TCSFCONTROLE controle, TREFMESUREACONTROLER mes, " +
"WHERE dossier.CODEDDAF = :codeDdaf ...";
SQLQuery sqlquery = session.createSQLQuery(requete);
sqlquery.setParameter("codeDdaf", codeDdaf);
BigDecimal result = (BigDecimal) sqlquery.uniqueResult();
• Chargement optimisé vs base de données
• Nécessite une projection - sinon retourne un Object[]
MD
-3-0
1-S
M-1
0 ré
v. B1
Fonctions de lecture
• Laquelle choisir ?
» Privilégier la qualité du logiciel :
id/asso criteria HQL SQL
» Lisibilité
» Performance
» Encapsulation
MD
-3-0
1-S
M-1
0 ré
v. B1