Your SlideShare is downloading. ×
0
Université Tunis El Manar Faculté des Sciences de Tunis Département des Sciences de l’Informatique Encadré par : M. Sadok ...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
Motivation L’Objet est devenu le style fondamentale de la programmation  Base de données OO Développement Conception Langa...
Solution ? ORM : Object / Relational Mapping  SQL Schéma relationnel ligne Table colonne Objet héritage attribut méthode p...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
ORM c’est quoi? Le mapping objet relationnel crée une illusion d’une BDOO à partir d’une BDR  public class Obj {   private...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
Hibernate : Framework de mapping O/R Il a été développé par un groupe de développeurs Java dirigés par Gavin King  POJO: P...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
POJO: - Personne - Prof - Etudiant - Filiere - Matiere Fichiers XML 11
package  persistClass; public   class  Matiere { private  String  nom ; private  Integer  codeMat ; public  Matiere(){} pu...
<ul><li>Le tag  <class>  permet de préciser des informations sur la classe qui va encapsuler les données. Ce tag possède p...
Pour assurer l’identité d’un objet « clé primaire pour une table », il faut redéfinir la méthode equals() des POJO public ...
15 <ul><li>Le tag  <property>,  fils du tag  <class> , permet de fournir des informations sur une propriété et sa correspo...
public   class  Etudiant  extends  Personne { private   float   moy ; public  Etudiant(){} public  Etudiant(Integer cin,St...
< class  name = &quot;persistClass.Personne&quot;  table = &quot;personne&quot; > < id  name = &quot;cin&quot;  type = &qu...
Relation plusieurs à plusieurs « many to many » Assurer la navigabilité: - on peut consulter et maj. l’ensemble des matièr...
Relation plusieurs à plusieurs « many to many » < set  name = &quot;mats&quot;  table = &quot;mat_fil&quot;  cascade = &qu...
La relation est bidirectionnelle: - Une filière pour plusieurs étudiants : Relation un à plusieurs « one to many » - Plusi...
< set  name = &quot;etds&quot;  inverse = &quot;true&quot;  cascade = &quot;all&quot; > < key  column = &quot;fil_affect&q...
POJO XML Mapping Schéma relationnel Middlegen ShemaExport hbm2ddl XDoclet CodeGenerator hbm2java Trop de code à écrire? Hi...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
On peut configurer hibernate soit par un fichier hibernate.properties soit par un fichier XML  hibernate.cfg.xml   soit pa...
<? xml  version = '1.0'  encoding = 'utf-8' ?> <! DOCTYPE  hibernate-configuration  PUBLIC &quot;-//Hibernate/Hibernate Co...
<ul><li>Pour une utilisation du fichier hibernate.cfg.xml, il faut  : </li></ul><ul><ul><li>- créer une occurrence de la c...
La SessionFactory nous permet d’ouvrir des sessions et des transactions import  persistClass.*; import  org.hibernate.*; i...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
Les requêtes Hibernate permet l’exécution des requêtes SQL standard. Hibernate s'occupera du mapping des résultats vers de...
Les requêtes Hibernate fournit un langage d'interrogation extrêmement puissant qui ressemble au SQL. HQL (Hibernate Query ...
Les requêtes Hibernate offre la possibilité de créer des requêtes dynamiquement à travers l’API Criteria. Criteria permet ...
32 La classe Session permet à travers ses différents méthodes de manipuler la persistance des objets. List personnes = ses...
Les objets que manipule une application peuvent passer par différents états. Un objet est dit persistant s’il est au moins...
Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul...
Mise en œuvre de l’exemple La classe qui contient notre main() La classe qui contient notre SessionFactory() Nos POJO XML ...
Merci pour votre attention
Upcoming SlideShare
Loading in...5
×

Hibernate

1,400

Published on

cours d'initiation au framework hibernate

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,400
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
175
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Hibernate"

  1. 1. 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
  2. 2. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>2
  3. 3. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>3
  4. 4. 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
  5. 5. Solution ? ORM : Object / Relational Mapping SQL Schéma relationnel ligne Table colonne Objet héritage attribut méthode polymorphisme Classe encapsulation 5
  6. 6. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>6
  7. 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. 8. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>8
  9. 9. 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
  10. 10. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>10
  11. 11. POJO: - Personne - Prof - Etudiant - Filiere - Matiere Fichiers XML 11
  12. 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. 13. <ul><li>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: </li></ul><ul><li>name : obligatoire, indiquant le POJO </li></ul><ul><li>table : obligatoire, indiquant de la table dans la base de données </li></ul><ul><li>dynamic−update : booléen qui indique de ne mettre à jour que les champs dont la valeur a été modifiée (false par défaut) </li></ul><ul><li>mutable : booléen qui indique si les occurrences peuvent être mises à jour (true par défaut) </li></ul>13
  14. 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 <ul><li>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 : </li></ul><ul><li>name : nom de la propriété dans la classe </li></ul><ul><li>type : le type Hibernate </li></ul><ul><li>column : le nom du champ dans la base de données (par défaut le nom de la propriété) </li></ul><ul><li>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 </li></ul>
  15. 15. 15 <ul><li>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 : </li></ul><ul><li>name : obligatoire, précise le nom de la propriété </li></ul><ul><li>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. </li></ul><ul><li>column : précise le nom du champ dans la base de données (par défaut le nom de la propriété) </li></ul><ul><li>update : précise si le champ est mis à jour lors d'une opération SQL de type update (par défaut true) </li></ul><ul><li>insert : précise si le champ est mis à jour lors d'une opération SQL de type insert (par défaut true) </li></ul>
  16. 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. 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. 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. 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. 20. 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
  21. 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. 22. 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
  23. 23. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>23
  24. 24. 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
  25. 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. 26. <ul><li>Pour une utilisation du fichier hibernate.cfg.xml, il faut : </li></ul><ul><ul><li>- créer une occurrence de la classe Configuration </li></ul></ul><ul><ul><li>- appeler sa méthode configure() qui va lire le fichier XML </li></ul></ul><ul><ul><li>- appeler la méthode buildSessionFactory() de l'objet renvoyé par la méthode configure(). </li></ul></ul>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. 27. 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
  28. 28. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>28
  29. 29. 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
  30. 30. 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
  31. 31. 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. 32. 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:
  33. 33. 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
  34. 34. Plan <ul><li>Motivation </li></ul><ul><li>Configuration de Hibernate </li></ul><ul><li>Présentation de Hibernate </li></ul><ul><li>Object Relational Mapping </li></ul><ul><li>Hibernate par l’exemple </li></ul><ul><li>Les requêtes avec Hibernate </li></ul><ul><li>Exécution de l’exemple </li></ul>34
  35. 35. 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
  36. 36. Merci pour votre attention
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×