La couche persistance hibernate
-
Upload
el-mekki-anouar -
Category
Technology
-
view
256 -
download
2
description
Transcript of La couche persistance hibernate
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