Université Tunis El Manar Faculté des Sciences de Tunis Département des Sciences de l’Informatique Encadré par : M. Sadok Ben Yahia Réalisé par : Megadmini Maher  (étudiant I4) La persistance des données avec Hibernate Année universitaire 2008/2009 Cours Web et Base de données
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 2
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 3
Motivation L’Objet est devenu le style fondamentale de la programmation  Base de données OO Développement Conception Langage orienté objet: java c# c++... UML O2, EyeBD Peu mature, peu expérimentée Coût de migration BDR vers BDOO Comment faire correspondance entre O/R BD Relationnelle ? :-/ ? ? 4
Solution ? ORM : Object / Relational Mapping  SQL Schéma relationnel ligne Table colonne Objet héritage attribut méthode polymorphisme Classe encapsulation 5
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 6
ORM c’est quoi? Le mapping objet relationnel crée une illusion d’une BDOO à partir d’une BDR  public class Obj {   private int id;   private String name;    public Obj(){ }   public Obj(String name) {     this.name = name;   }   public void setId(int i) {     id = i;   } …. } Il existe plusieurs Framework de mapping objet/relationnel : Java Persistance API, TopLink, Java Data Object, Hibernate, Object Relational Bridge… Donc on peut bénéficier de l’orienté objet et gérer une BD relationnelle d’une façon transparente. 7 .. … .. … .. .. name Id
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 8
Hibernate : Framework de mapping O/R Il a été développé par un groupe de développeurs Java dirigés par Gavin King  POJO: Plain Old Java Object « bon vieil objet java » : une classe de type javabean qui doit encapsuler les propriétés dans des champs  private  avec des getters et setters et avoir au moins un constructeur sans paramètre Tables Relationnelles Différents propriétés de configuration : connexion, url de la BD, Dialect utilisé… Le mapping est assuré par des fichiers XML Hibernate est un Framework open source gérant la persistance des objets en base de données relationnelle. 9
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 10
POJO: - Personne - Prof - Etudiant - Filiere - Matiere Fichiers XML 11
package  persistClass; public   class  Matiere { private  String  nom ; private  Integer  codeMat ; public  Matiere(){} public  Matiere(Integer code,String nom) { this . nom  = nom; this . codeMat =code; } public  String getNom() { return   nom ; } public   void  setNom(String nom) { this . nom  = nom; } public  Integer getCodeMat() { return   codeMat ; } public   void  setCodeMat(Integer code) { this . codeMat  = code; } } <? xml  version = &quot;1.0&quot; ?> <! DOCTYPE  hibernate-mapping  PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot; &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot; > < hibernate-mapping > < class  name = &quot;persistClass.Matiere&quot;  table = &quot;matiere&quot; > < id  name = &quot;codeMat&quot;  type = &quot;int&quot;  column = &quot;code_mat&quot; ></ id > < property  name = &quot;nom&quot;  type = &quot;string&quot;  length = &quot;50&quot;  column = &quot;nom_mat&quot; /> </ class > </ hibernate-mapping > - Ce fichier xml sera sauvegardé sous le nom Matiere.hbm.xml et dans le même répertoire que son POJO correspondant. - On peut aussi mapper tous les POJO dans un seul fichier. 12 package POJO attribut Clé primaire
Le tag  <class>  permet de préciser des informations sur la classe qui va encapsuler les données. Ce tag possède plusieurs attributs dont les principaux sont: name  : obligatoire, indiquant le POJO table  : obligatoire, indiquant de la table dans la base de données dynamic−update   : booléen qui indique de ne mettre à jour que les champs dont la valeur a été modifiée (false par défaut) mutable  : booléen qui indique si les occurrences peuvent être mises à jour (true par défaut) 13
Pour assurer l’identité d’un objet « clé primaire pour une table », il faut redéfinir la méthode equals() des POJO public   boolean  equals(Object other) { if  ( this  == other)  return   true ; if  ( !(other  instanceof  Matiere) ) return   false ; final  Matiere mat = (Matiere) other; if  (!mat.getCodeMat().equals( getCodeMat() )  return   false ; return   true ; } 14 Le tag enfant  <id>  du tag  <class>  permet de fournir des informations sur l'identifiant d'une occurrence dans la table. Ce tag possède plusieurs attributs : name   : nom de la propriété dans la classe type   : le type Hibernate column   : le nom du champ dans la base de données (par défaut le nom de la propriété) unsaved−value  : Une valeur de la propriété d'identifiant qui indique que l'instance est nouvellement instanciée (non sauvegardée), et qui la distingue des instances qui ont été sauvegardées ou chargées de la base
15 Le tag  <property>,  fils du tag  <class> , permet de fournir des informations sur une propriété et sa correspondance avec un champ dans la base de données. Ce tag possède plusieurs attributs dont les principaux sont : name  : obligatoire, précise le nom de la propriété type  : précise le type qui doit être soit un type Hibernate (integer, string, date, timestamp, ...), soit les types primitifs java et certaines classes de base (int, java.lang.String, float, java.util.Date, ...), soit une classe qui encapsule des données à rendre persistante. column   : précise le nom du champ dans la base de données (par défaut le nom de la propriété) update  : précise si le champ est mis à jour lors d'une opération SQL de type update (par défaut true) insert   : précise si le champ est mis à jour lors d'une opération SQL de type insert (par défaut true)
public   class  Etudiant  extends  Personne { private   float   moy ; public  Etudiant(){} public  Etudiant(Integer cin,String nom,String prenom){ super (cin,nom,prenom); } //Getters and Setters } public   class  Prof  extends  Personne { private  String  grade ; public  Prof(){} public  Prof(Integer cin,String nom,String prenom,String grade){ super (cin,nom,prenom); this . grade =grade; } //Getters and Setters } public   class  Personne { private  Integer  cin ; private  String  nom ; private  String  prenom ; public  Personne(){ } public  Personne(Integer cin,String nom,String prenom) { this . cin  = cin; this . nom =nom; this . prenom =prenom; } //Getters and Setters } Personne( cin , nom, prenom) Prof( cin# , grade) Etudiant( cin# , moy_et) Hibernate offre différents stratégies pour mapper l’héritage: - <subclass> - <union-subclass> -  <joined-subclass> 16
< class  name = &quot;persistClass.Personne&quot;  table = &quot;personne&quot; > < id  name = &quot;cin&quot;  type = &quot;int&quot;  column = &quot;cin_pers&quot; ></ id > < property  name = &quot;nom&quot;  type = &quot;string&quot;  length = &quot;50&quot;  column = &quot;nom_pers&quot; /> < property  name = &quot;prenom&quot;  type = &quot;string&quot;  length = &quot;50&quot;  column = &quot;prenom_pers&quot; /> < joined-subclass  name = &quot;persistClass.Etudiant&quot;  table = &quot;etudiant&quot; >   < key  column = &quot;cin&quot; />   < property  name = &quot;moyenne&quot;  type = &quot;float&quot;  column = &quot;moy_et&quot; /> </ joined-subclass > < joined-subclass  name = &quot;persistClass.Prof&quot;  table = &quot;prof&quot; >   < key  column = &quot;cin&quot; />   < property  name = &quot;grade&quot;  type = &quot;string&quot;  column = &quot;grade&quot; /> </ joined-subclass > </ class > 17 Identifiants hérités Clés référencées Attributs propres aux classes filles
Relation plusieurs à plusieurs « many to many » Assurer la navigabilité: - on peut consulter et maj. l’ensemble des matières d’une filière donnée - on peut consulter dans quelles filières est étudiée une matière donnée et maj. cet ensemble de filières public   class  Filiere { … private  Set  mats = new  HashSet(); public  Set getMats() { return   mats ; } public   void  setMats(Set mats) { this . mats  = mats; } } fil1.getMats().add(mat1); fil1.getMats().remove(mat3); Le bon fonctionnement des Set (ou autre collection) nécessite la redéfinition de la méthode hashCode() 18
Relation plusieurs à plusieurs « many to many » < set  name = &quot;mats&quot;  table = &quot;mat_fil&quot;  cascade = &quot;all&quot; > < key  column = &quot;code_fil&quot; /> < many-to-many  column = &quot;code_mat&quot; class = &quot;persistClass.Matiere&quot; /> </ set > cascade (optionnel - par défaut = none) : active les opérations de cascade vers les entités filles cascade=&quot;all | none | save-update | delete | all-delete-orphan&quot; 19 La nouvelle table du à la relation « many to many » Cette table n’a pas besoin d’être mapper ou représenté par une POJO sauf dans le cas ou elle contient autre propriétés que les deux clés étrangères. On mappe la classe Matiere de la même façon (en changeant le nécessaire) pour avoir une relation bidirectionnelle.
La relation est bidirectionnelle: - Une filière pour plusieurs étudiants : Relation un à plusieurs « one to many » - Plusieurs étudiants pour une filière : Relation plusieurs à un « many to one » public   class  Etudiant  extends  Personne { … private  Filiere  fil ; //Getter and Setter … } public   class  Filiere { … private  Set  etds = new  HashSet(); public  Set getEtds() { return   etds ; } public   void  setEtds(Set etds) { this . etds  = etds; } public   void  addEtds(Etudiant et){ et.setFil( this ); this .getEtds().add(et); }} Optimisation du code 20
< set  name = &quot;etds&quot;  inverse = &quot;true&quot;  cascade = &quot;all&quot; > < key  column = &quot;fil_affect&quot;  /> < one-to-many  class = &quot;persistClass.Etudiant&quot; /> </ set > < joined-subclass  name = &quot;persistClass.Etudiant&quot;  table = &quot;etudiant&quot; > … < many-to-one  name = &quot;fil&quot;  column = &quot;fil_affect&quot; /> </ joined-subclass > inverse (optionnel - par défaut = false) : définit cette collection comme l'extrémité &quot;inverse&quot; de l'association bidirectionnelle 21
POJO XML Mapping Schéma relationnel Middlegen ShemaExport hbm2ddl XDoclet CodeGenerator hbm2java Trop de code à écrire? Hibernate vous facilite la tâche et met en disposition le package Hibernate tools (ensemble d’outils de génération avec Ant) 22
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 23
On peut configurer hibernate soit par un fichier hibernate.properties soit par un fichier XML  hibernate.cfg.xml   soit par programmation. Configuration Dans la configuration on doit indiquer à Hibernate: - les SessionFactory de notre application (une fabrique de session responsable d’une base de données) Avec une SessionFactory on peut : - Configurer l’accès à la BD (driver, url, login, pw…) - Configurer le pool de connexion (nombre min-max des connexions, temps d’inactivité max pour une connexion…) 24
<? xml  version = '1.0'  encoding = 'utf-8' ?> <! DOCTYPE  hibernate-configuration  PUBLIC &quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot; &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot; > < hibernate-configuration > < session-factory > < property  name = &quot;connection.driver_class&quot; > com.mysql.jdbc.Driver </ property > < property  name = &quot;connection.url&quot; > jdbc:mysql://localhost:3306/exphib </ property > < property  name = &quot;connection.username&quot; > root </ property > < property  name = &quot;connection.password&quot; ></ property > < property  name = &quot;connection.pool_size&quot; > 1 </ property > < property  name = &quot;dialect&quot; > org.hibernate.dialect.MySQLDialect </ property > < property  name = &quot;current_session_context_class&quot; > thread </ property > < property  name = &quot;cache.provider_class&quot; > org.hibernate.cache.NoCacheProvider </ property > < property  name = &quot;show_sql&quot; > true </ property > < property  name = &quot;hbm2ddl.auto&quot; > create </ property > < mapping  resource = &quot;persistClass/Personne.hbm.xml&quot; /> < mapping  resource = &quot;persistClass/Matiere.hbm.xml&quot; /> < mapping  resource = &quot;persistClass/Filiere.hbm.xml&quot; /> </ session-factory > </ hibernate-configuration > La SessionFactory de notre unique base Configuration de la connexion avec la base (driver, url, login, mot de passe..) Configuration de pool de connexion Indication du Dialect Configuration de cache Afficher les requêtes SQL sur la console Génération automatique de la base (drop if exist) Fichiers XML de mapping 25
Pour une utilisation du fichier hibernate.cfg.xml, il faut  : - créer une occurrence de la classe Configuration - appeler sa méthode configure() qui va lire le fichier XML  - appeler la méthode buildSessionFactory() de l'objet renvoyé par la méthode configure(). package  persistance; import  org.hibernate.*; import  org.hibernate.cfg.*; public   class  HibernateUtil { private   static  SessionFactory  sessionFactory ; static  { try  { sessionFactory  =  new  Configuration().configure().buildSessionFactory(); } catch  (Throwable ex) { throw   new  ExceptionInInitializerError(ex); } } public   static  SessionFactory getSessionFactory() { return   sessionFactory ; } public   static   void  shutdown() { getSessionFactory ().close(); }} 26
La SessionFactory nous permet d’ouvrir des sessions et des transactions import  persistClass.*; import  org.hibernate.*; import  persistance.HibernateUtil; public   class  Tester { public   static   void  main(String[] args) { //ouvrir une session Session session1 = HibernateUtil. getSessionFactory ().openSession(); //commencer une transaction Transaction tx1 = session1.beginTransaction(); //consulter modifier la base //fermer la transaction tx1.commit(); //fermer la session session1.close(); }} 27
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 28
Les requêtes Hibernate permet l’exécution des requêtes SQL standard. Hibernate s'occupera du mapping des résultats vers des objets.  Exemple: List mats = session1.createSQLQuery( &quot;select * from matiere&quot; )   .addEntity(Matiere. class )   .list(); Float max = (Float) session1.createSQLQuery( &quot;select  max(etudiant.moy_et) as moy from etudiant e&quot; ) .addScalar( &quot;moy&quot; , Hibernate. FLOAT ) .uniqueResult(); 29
Les requêtes Hibernate fournit un langage d'interrogation extrêmement puissant qui ressemble au SQL. HQL (Hibernate Query Language) est totalement orienté objet, comprenant des notions d'héritage, de polymorphisme et d'association. Les éléments que l'ont spécifie font parti de l'objet persistant, et non de la base de donnée. Pour bien comprendre Hibernate, il faut raisonner en Objet et pas en terme de SGBD relationnel.  « www.labo-sun.com » Exemple: List pers = session1.createQuery(   &quot;select * from Personne  where Personne.name = ?&quot; )   .setString(0,  &quot;ali&quot; )   .List(); 30
Les requêtes Hibernate offre la possibilité de créer des requêtes dynamiquement à travers l’API Criteria. Criteria permet de requêter la base selon un critère de recherche donnée. Exemple: session1.createCriteria(Filiere. class ) .add( Expression.like( &quot;nom&quot; ,  &quot;sciences%&quot; ) ); Criteria crit = session1.createCriteria(Personne. class ); crit.addOrder( Order.asc( &quot;name&quot; ) ); List results = crit.list(); List etudiant = session1.createCriteria(Etudiant. class )   .add(Restrictions. between ( &quot;code&quot; , new  Integer(100), new  Integer(199)))   .list(); 31
32 La classe Session permet à travers ses différents méthodes de manipuler la persistance des objets. List personnes = session.find( &quot;from Personne p where p.nom=?&quot; , &quot;ali&quot; , Hibernate. STRING ); int  compteur = ( (Integer) session.iterate( &quot;select count(*)  from Personnes&quot; ).next() ).intValue(); int  pers = session.delete( &quot;from Personne p where  p.nom=?&quot; , &quot;ali&quot; , Hibernate. STRING ); Personne pers = (Personne) sess.load(Personne. class ,  new   Integer(21)); Exemple:
Les objets que manipule une application peuvent passer par différents états. Un objet est dit persistant s’il est au moins sauvegardé dans le cache Après d’être détaché d’une transaction Un objet est éphémère (passager) s’il n’est pas encore lié à une transaction ou bien supprimé de la base 33
Plan Motivation Configuration de Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 34
Mise en œuvre de l’exemple La classe qui contient notre main() La classe qui contient notre SessionFactory() Nos POJO XML de Mapping Fichiers de configuration de Hibernate Fichier Log similaire à celui d’un SGBD Il affiche les messages des traces sur la console. Les différents .jar pour assurer le fonctionnement de Hibernate Le driver de la base 35
Merci pour votre attention

Hibernate

  • 1.
    Université Tunis ElManar Faculté des Sciences de Tunis Département des Sciences de l’Informatique Encadré par : M. Sadok Ben Yahia Réalisé par : Megadmini Maher (étudiant I4) La persistance des données avec Hibernate Année universitaire 2008/2009 Cours Web et Base de données
  • 2.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 2
  • 3.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 3
  • 4.
    Motivation L’Objet estdevenu le style fondamentale de la programmation Base de données OO Développement Conception Langage orienté objet: java c# c++... UML O2, EyeBD Peu mature, peu expérimentée Coût de migration BDR vers BDOO Comment faire correspondance entre O/R BD Relationnelle ? :-/ ? ? 4
  • 5.
    Solution ? ORM: Object / Relational Mapping SQL Schéma relationnel ligne Table colonne Objet héritage attribut méthode polymorphisme Classe encapsulation 5
  • 6.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 6
  • 7.
    ORM c’est quoi?Le mapping objet relationnel crée une illusion d’une BDOO à partir d’une BDR public class Obj {   private int id;   private String name;    public Obj(){ }   public Obj(String name) {     this.name = name;   }   public void setId(int i) {     id = i;   } …. } Il existe plusieurs Framework de mapping objet/relationnel : Java Persistance API, TopLink, Java Data Object, Hibernate, Object Relational Bridge… Donc on peut bénéficier de l’orienté objet et gérer une BD relationnelle d’une façon transparente. 7 .. … .. … .. .. name Id
  • 8.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 8
  • 9.
    Hibernate : Frameworkde mapping O/R Il a été développé par un groupe de développeurs Java dirigés par Gavin King POJO: Plain Old Java Object « bon vieil objet java » : une classe de type javabean qui doit encapsuler les propriétés dans des champs private avec des getters et setters et avoir au moins un constructeur sans paramètre Tables Relationnelles Différents propriétés de configuration : connexion, url de la BD, Dialect utilisé… Le mapping est assuré par des fichiers XML Hibernate est un Framework open source gérant la persistance des objets en base de données relationnelle. 9
  • 10.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 10
  • 11.
    POJO: - Personne- Prof - Etudiant - Filiere - Matiere Fichiers XML 11
  • 12.
    package persistClass;public class Matiere { private String nom ; private Integer codeMat ; public Matiere(){} public Matiere(Integer code,String nom) { this . nom = nom; this . codeMat =code; } public String getNom() { return nom ; } public void setNom(String nom) { this . nom = nom; } public Integer getCodeMat() { return codeMat ; } public void setCodeMat(Integer code) { this . codeMat = code; } } <? xml version = &quot;1.0&quot; ?> <! DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot; &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot; > < hibernate-mapping > < class name = &quot;persistClass.Matiere&quot; table = &quot;matiere&quot; > < id name = &quot;codeMat&quot; type = &quot;int&quot; column = &quot;code_mat&quot; ></ id > < property name = &quot;nom&quot; type = &quot;string&quot; length = &quot;50&quot; column = &quot;nom_mat&quot; /> </ class > </ hibernate-mapping > - Ce fichier xml sera sauvegardé sous le nom Matiere.hbm.xml et dans le même répertoire que son POJO correspondant. - On peut aussi mapper tous les POJO dans un seul fichier. 12 package POJO attribut Clé primaire
  • 13.
    Le tag <class> permet de préciser des informations sur la classe qui va encapsuler les données. Ce tag possède plusieurs attributs dont les principaux sont: name : obligatoire, indiquant le POJO table : obligatoire, indiquant de la table dans la base de données dynamic−update : booléen qui indique de ne mettre à jour que les champs dont la valeur a été modifiée (false par défaut) mutable : booléen qui indique si les occurrences peuvent être mises à jour (true par défaut) 13
  • 14.
    Pour assurer l’identitéd’un objet « clé primaire pour une table », il faut redéfinir la méthode equals() des POJO public boolean equals(Object other) { if ( this == other) return true ; if ( !(other instanceof Matiere) ) return false ; final Matiere mat = (Matiere) other; if (!mat.getCodeMat().equals( getCodeMat() ) return false ; return true ; } 14 Le tag enfant <id> du tag <class> permet de fournir des informations sur l'identifiant d'une occurrence dans la table. Ce tag possède plusieurs attributs : name : nom de la propriété dans la classe type : le type Hibernate column : le nom du champ dans la base de données (par défaut le nom de la propriété) unsaved−value : Une valeur de la propriété d'identifiant qui indique que l'instance est nouvellement instanciée (non sauvegardée), et qui la distingue des instances qui ont été sauvegardées ou chargées de la base
  • 15.
    15 Le tag <property>, fils du tag <class> , permet de fournir des informations sur une propriété et sa correspondance avec un champ dans la base de données. Ce tag possède plusieurs attributs dont les principaux sont : name : obligatoire, précise le nom de la propriété type : précise le type qui doit être soit un type Hibernate (integer, string, date, timestamp, ...), soit les types primitifs java et certaines classes de base (int, java.lang.String, float, java.util.Date, ...), soit une classe qui encapsule des données à rendre persistante. column : précise le nom du champ dans la base de données (par défaut le nom de la propriété) update : précise si le champ est mis à jour lors d'une opération SQL de type update (par défaut true) insert : précise si le champ est mis à jour lors d'une opération SQL de type insert (par défaut true)
  • 16.
    public class Etudiant extends Personne { private float moy ; public Etudiant(){} public Etudiant(Integer cin,String nom,String prenom){ super (cin,nom,prenom); } //Getters and Setters } public class Prof extends Personne { private String grade ; public Prof(){} public Prof(Integer cin,String nom,String prenom,String grade){ super (cin,nom,prenom); this . grade =grade; } //Getters and Setters } public class Personne { private Integer cin ; private String nom ; private String prenom ; public Personne(){ } public Personne(Integer cin,String nom,String prenom) { this . cin = cin; this . nom =nom; this . prenom =prenom; } //Getters and Setters } Personne( cin , nom, prenom) Prof( cin# , grade) Etudiant( cin# , moy_et) Hibernate offre différents stratégies pour mapper l’héritage: - <subclass> - <union-subclass> - <joined-subclass> 16
  • 17.
    < class name = &quot;persistClass.Personne&quot; table = &quot;personne&quot; > < id name = &quot;cin&quot; type = &quot;int&quot; column = &quot;cin_pers&quot; ></ id > < property name = &quot;nom&quot; type = &quot;string&quot; length = &quot;50&quot; column = &quot;nom_pers&quot; /> < property name = &quot;prenom&quot; type = &quot;string&quot; length = &quot;50&quot; column = &quot;prenom_pers&quot; /> < joined-subclass name = &quot;persistClass.Etudiant&quot; table = &quot;etudiant&quot; > < key column = &quot;cin&quot; /> < property name = &quot;moyenne&quot; type = &quot;float&quot; column = &quot;moy_et&quot; /> </ joined-subclass > < joined-subclass name = &quot;persistClass.Prof&quot; table = &quot;prof&quot; > < key column = &quot;cin&quot; /> < property name = &quot;grade&quot; type = &quot;string&quot; column = &quot;grade&quot; /> </ joined-subclass > </ class > 17 Identifiants hérités Clés référencées Attributs propres aux classes filles
  • 18.
    Relation plusieurs àplusieurs « many to many » Assurer la navigabilité: - on peut consulter et maj. l’ensemble des matières d’une filière donnée - on peut consulter dans quelles filières est étudiée une matière donnée et maj. cet ensemble de filières public class Filiere { … private Set mats = new HashSet(); public Set getMats() { return mats ; } public void setMats(Set mats) { this . mats = mats; } } fil1.getMats().add(mat1); fil1.getMats().remove(mat3); Le bon fonctionnement des Set (ou autre collection) nécessite la redéfinition de la méthode hashCode() 18
  • 19.
    Relation plusieurs àplusieurs « many to many » < set name = &quot;mats&quot; table = &quot;mat_fil&quot; cascade = &quot;all&quot; > < key column = &quot;code_fil&quot; /> < many-to-many column = &quot;code_mat&quot; class = &quot;persistClass.Matiere&quot; /> </ set > cascade (optionnel - par défaut = none) : active les opérations de cascade vers les entités filles cascade=&quot;all | none | save-update | delete | all-delete-orphan&quot; 19 La nouvelle table du à la relation « many to many » Cette table n’a pas besoin d’être mapper ou représenté par une POJO sauf dans le cas ou elle contient autre propriétés que les deux clés étrangères. On mappe la classe Matiere de la même façon (en changeant le nécessaire) pour avoir une relation bidirectionnelle.
  • 20.
    La relation estbidirectionnelle: - Une filière pour plusieurs étudiants : Relation un à plusieurs « one to many » - Plusieurs étudiants pour une filière : Relation plusieurs à un « many to one » public class Etudiant extends Personne { … private Filiere fil ; //Getter and Setter … } public class Filiere { … private Set etds = new HashSet(); public Set getEtds() { return etds ; } public void setEtds(Set etds) { this . etds = etds; } public void addEtds(Etudiant et){ et.setFil( this ); this .getEtds().add(et); }} Optimisation du code 20
  • 21.
    < set name = &quot;etds&quot; inverse = &quot;true&quot; cascade = &quot;all&quot; > < key column = &quot;fil_affect&quot; /> < one-to-many class = &quot;persistClass.Etudiant&quot; /> </ set > < joined-subclass name = &quot;persistClass.Etudiant&quot; table = &quot;etudiant&quot; > … < many-to-one name = &quot;fil&quot; column = &quot;fil_affect&quot; /> </ joined-subclass > inverse (optionnel - par défaut = false) : définit cette collection comme l'extrémité &quot;inverse&quot; de l'association bidirectionnelle 21
  • 22.
    POJO XML MappingSchéma relationnel Middlegen ShemaExport hbm2ddl XDoclet CodeGenerator hbm2java Trop de code à écrire? Hibernate vous facilite la tâche et met en disposition le package Hibernate tools (ensemble d’outils de génération avec Ant) 22
  • 23.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 23
  • 24.
    On peut configurerhibernate soit par un fichier hibernate.properties soit par un fichier XML hibernate.cfg.xml soit par programmation. Configuration Dans la configuration on doit indiquer à Hibernate: - les SessionFactory de notre application (une fabrique de session responsable d’une base de données) Avec une SessionFactory on peut : - Configurer l’accès à la BD (driver, url, login, pw…) - Configurer le pool de connexion (nombre min-max des connexions, temps d’inactivité max pour une connexion…) 24
  • 25.
    <? xml version = '1.0' encoding = 'utf-8' ?> <! DOCTYPE hibernate-configuration PUBLIC &quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot; &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot; > < hibernate-configuration > < session-factory > < property name = &quot;connection.driver_class&quot; > com.mysql.jdbc.Driver </ property > < property name = &quot;connection.url&quot; > jdbc:mysql://localhost:3306/exphib </ property > < property name = &quot;connection.username&quot; > root </ property > < property name = &quot;connection.password&quot; ></ property > < property name = &quot;connection.pool_size&quot; > 1 </ property > < property name = &quot;dialect&quot; > org.hibernate.dialect.MySQLDialect </ property > < property name = &quot;current_session_context_class&quot; > thread </ property > < property name = &quot;cache.provider_class&quot; > org.hibernate.cache.NoCacheProvider </ property > < property name = &quot;show_sql&quot; > true </ property > < property name = &quot;hbm2ddl.auto&quot; > create </ property > < mapping resource = &quot;persistClass/Personne.hbm.xml&quot; /> < mapping resource = &quot;persistClass/Matiere.hbm.xml&quot; /> < mapping resource = &quot;persistClass/Filiere.hbm.xml&quot; /> </ session-factory > </ hibernate-configuration > La SessionFactory de notre unique base Configuration de la connexion avec la base (driver, url, login, mot de passe..) Configuration de pool de connexion Indication du Dialect Configuration de cache Afficher les requêtes SQL sur la console Génération automatique de la base (drop if exist) Fichiers XML de mapping 25
  • 26.
    Pour une utilisationdu fichier hibernate.cfg.xml, il faut : - créer une occurrence de la classe Configuration - appeler sa méthode configure() qui va lire le fichier XML - appeler la méthode buildSessionFactory() de l'objet renvoyé par la méthode configure(). package persistance; import org.hibernate.*; import org.hibernate.cfg.*; public class HibernateUtil { private static SessionFactory sessionFactory ; static { try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory ; } public static void shutdown() { getSessionFactory ().close(); }} 26
  • 27.
    La SessionFactory nouspermet d’ouvrir des sessions et des transactions import persistClass.*; import org.hibernate.*; import persistance.HibernateUtil; public class Tester { public static void main(String[] args) { //ouvrir une session Session session1 = HibernateUtil. getSessionFactory ().openSession(); //commencer une transaction Transaction tx1 = session1.beginTransaction(); //consulter modifier la base //fermer la transaction tx1.commit(); //fermer la session session1.close(); }} 27
  • 28.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 28
  • 29.
    Les requêtes Hibernatepermet l’exécution des requêtes SQL standard. Hibernate s'occupera du mapping des résultats vers des objets. Exemple: List mats = session1.createSQLQuery( &quot;select * from matiere&quot; ) .addEntity(Matiere. class ) .list(); Float max = (Float) session1.createSQLQuery( &quot;select max(etudiant.moy_et) as moy from etudiant e&quot; ) .addScalar( &quot;moy&quot; , Hibernate. FLOAT ) .uniqueResult(); 29
  • 30.
    Les requêtes Hibernatefournit un langage d'interrogation extrêmement puissant qui ressemble au SQL. HQL (Hibernate Query Language) est totalement orienté objet, comprenant des notions d'héritage, de polymorphisme et d'association. Les éléments que l'ont spécifie font parti de l'objet persistant, et non de la base de donnée. Pour bien comprendre Hibernate, il faut raisonner en Objet et pas en terme de SGBD relationnel. « www.labo-sun.com » Exemple: List pers = session1.createQuery( &quot;select * from Personne where Personne.name = ?&quot; ) .setString(0, &quot;ali&quot; ) .List(); 30
  • 31.
    Les requêtes Hibernateoffre la possibilité de créer des requêtes dynamiquement à travers l’API Criteria. Criteria permet de requêter la base selon un critère de recherche donnée. Exemple: session1.createCriteria(Filiere. class ) .add( Expression.like( &quot;nom&quot; , &quot;sciences%&quot; ) ); Criteria crit = session1.createCriteria(Personne. class ); crit.addOrder( Order.asc( &quot;name&quot; ) ); List results = crit.list(); List etudiant = session1.createCriteria(Etudiant. class ) .add(Restrictions. between ( &quot;code&quot; , new Integer(100), new Integer(199))) .list(); 31
  • 32.
    32 La classeSession permet à travers ses différents méthodes de manipuler la persistance des objets. List personnes = session.find( &quot;from Personne p where p.nom=?&quot; , &quot;ali&quot; , Hibernate. STRING ); int compteur = ( (Integer) session.iterate( &quot;select count(*) from Personnes&quot; ).next() ).intValue(); int pers = session.delete( &quot;from Personne p where p.nom=?&quot; , &quot;ali&quot; , Hibernate. STRING ); Personne pers = (Personne) sess.load(Personne. class , new Integer(21)); Exemple:
  • 33.
    Les objets quemanipule une application peuvent passer par différents états. Un objet est dit persistant s’il est au moins sauvegardé dans le cache Après d’être détaché d’une transaction Un objet est éphémère (passager) s’il n’est pas encore lié à une transaction ou bien supprimé de la base 33
  • 34.
    Plan Motivation Configurationde Hibernate Présentation de Hibernate Object Relational Mapping Hibernate par l’exemple Les requêtes avec Hibernate Exécution de l’exemple 34
  • 35.
    Mise en œuvrede l’exemple La classe qui contient notre main() La classe qui contient notre SessionFactory() Nos POJO XML de Mapping Fichiers de configuration de Hibernate Fichier Log similaire à celui d’un SGBD Il affiche les messages des traces sur la console. Les différents .jar pour assurer le fonctionnement de Hibernate Le driver de la base 35
  • 36.