Vous êtes sur la page 1sur 36

Framework de persistance

(Hibernate)

2 ISIC – Semestre 3

Pr. Mohamed LACHGAR


25/10/23 ENSAJ
MySQL
Oracle
SQLServer
JDBC …
Hibernate
EclipseLink

Java Swing
JSP / Servlet
Struts
JSF

25/10/23 ENSAJ
 Dans cette architecture, nous distinguons :
 le système de gestion de base de données (SGBD), qui stocke les
données utilisées par l'application,
 la couche d'accès aux données, en charge de l'accès aux données et
de leur manipulation, indépendamment du SGBD choisi,
 la couche métier, gère la logique de l'application,
 la couche service : correspondant à la mise en œuvre de l'ensemble
des règles de gestion et de la logique applicative,
 la couche présentation, qui s'occupe à la fois d'afficher les données
reçues par la couche de services et d'envoyer à la couche de services
les informations relatives aux actions de l'utilisateur.

25/10/23 ENSAJ
Users:Collection

:User
idUser=1 Hibernate est un Framework Java de persistance qui permet
login=root de faire correspondre des tables de base de données
pass=root relationnelles avec des objets java.
email=root@yahoo.fr
ville=casa Une fois la correspondance entre les deux mondes définie, le
programme Java peut manipuler toutes les données en
:User
utilisant que des JavaBean, masquant alors totalement la base
idUser=2 de données sous-jacente et ses spécificités. Le Framework
login=toto assure le remplissage de ces objets et la mise à jour de la base
pass=toto en se basant sur leur contenu.
email=toto@yahoo.fr
ville=rabat Base de données relationnelle
:User
idUser=3
login=you
pass=you
email=med@yahoo.fr
ville=casa
25/10/23 ENSAJ
 Hibernate est un framework de mapping Objet/Relationnel pour
applications JAVA (et .NET avec Nhibernate).
 Le terme mapping objet/relationnel (ORM) décrit la technique consistant
à faire le lien entre la représentation objet des données et sa
représentation relationnelle basée sur un schéma SQL.
 Hibernate génère le code SQL :
 Pas de requête SQL à écrire,

 Pas d’Objet ResultSet à gérer,

 Application plus portable. S’adapte à la base de données cible.

25/10/23 ENSAJ
 Hibernate s'occupe du transfert des objets Java dans les tables de la base
de données
 En plus, il permet de requêter les données et propose des moyens de les
récupérer.
 Il peut donc réduire de manière significative le temps de développement
qui aurait été autrement perdu dans une manipulation manuelle des
données via SQL et JDBC

25/10/23 ENSAJ
 Le but d'Hibernate est de libérer le développeur de 95 pourcent des tâches
de programmation liées à la persistance des données communes.
 Hibernate assure la portabilité de votre application si vous changer de SGBD.
 Hibernate n'est probablement pas la meilleure solution pour les applications
centrées sur les données qui n'utilisent que les procédures stockées pour
implémenter la logique métier dans la base de données,
 Il est le plus utile dans les modèles métier orientés objets dont la logique
métier est implémentée dans la couche Java dite intermédiaire.
 Hibernate propose au développeur des méthodes d’accès aux bases de
données plus efficace ce qui devrait rassurer les développeurs.

25/10/23 ENSAJ
25/10/23 ENSAJ
 SessionFactory (org.hibernate.SessionFactory) : Un cache threadsafe
(immuable) de mappages compilés pour une base de données. En tant que
fabrique de Session et que client du ConnectionProvider, SessionFactory
peut contenir un cache optionnel de données (de second niveau),
réutilisable entre les différentes transactions, que cela soit au sein du
même processus ou au niveau d'un cluster.

 Session (org.hibernate.Session) : Un objet mono-threadé, à durée de vie


courte, qui représente une conversation entre l'application et l'entrepôt de
persistance. Encapsule une connexion JDBC. Fabrique des
objets Transaction. La Session contient un cache (de premier niveau) des
objets persistants, qui sont utilisés lors de la navigation dans le graphe
d'objets ou lors de la récupération d'objets par leur identifiant.

25/10/23 ENSAJ
 Objets et collections persistants : Objets mono-threadés à vie courte,
contenant état persistant et fonction commerciale. Ceux-ci sont en général
des objets ordinaires de type JavaBean (ou POJO); la seule particularité est
qu'ils sont associés avec une (et une seule) Session. Dès que la Session est
fermée, ils sont détachés et libres d'être utilisés par n'importe quelle
couche de l'application (par ex. de et vers la présentation).

 Objets et collections éphémères (transient) et détachés : Instances de


classes persistantes qui ne sont actuellement pas associées à une Session.
Elles ont pu être instanciées par l'application et ne pas avoir (encore) été
persistées, ou elle ont pu être instanciées par une Session fermée.

25/10/23 ENSAJ
 Transaction (org.hibernate.Transaction)(Optionnel) : Un objet mono-threadé à vie
courte utilisé par l'application pour définir une unité de travail atomique. Abstrait
l'application des transactions sous-jacentes, qu'elles soient JDBC, JTA ou CORBA.
Une Session peut fournir plusieurs Transactions dans certains cas. Toutefois, la
délimitation des transactions, via l'API d'Hibernate ou par la Transaction sous-
jacente, n'est jamais optionnelle.

 ConnectionProvider (org.hibernate.connection.ConnectionProvider)(Optionnel) :
Une fabrique de (pool de) connexions JDBC. Abstrait l'application de
la Datasource ou du DriverManager sous-jacent. Non exposé à l'application, mais
peut être étendu/implémenté par le développeur.

 TransactionFactory (org.hibernate.TransactionFactory)(Optionnel) : Une fabrique


d'instances de Transaction. Non exposée à l'application, mais peut être
étendue/implémentée par le développeur.

25/10/23 ENSAJ
 éphémère (transient) : L'instance n'est pas et n'a jamais été associée à un
contexte de persistance. Elle ne possède pas d'identité persistante (valeur de clé
primaire).

 Persistant : L'instance est associée à un contexte de persistance. Elle possède


une identité persistante (valeur de clé primaire) et, peut-être un enregistrement
correspondant dans la base de données. Pour un contexte de persistance
particulier, Hibernate garantit que l'identité persistante soit équivalente à
l'identité Java (emplacement mémoire de l'objet).

 Détaché : L'instance a été associée au contexte de persistance mais ce contexte


a été fermé, ou l'instance a été sérialisée vers un autre processus. Elle possède
une identité persistante et peut-être un enregistrement correspondant dans la
base de données. Pour des instances détachées, Hibernate ne donne aucune
garantie sur la relation entre l'identité persistante et l'identité Java.

25/10/23 ENSAJ
Hibernate a besoin de plusieurs éléments pour fonctionner :

 Une classe de type JavaBean qui encapsule les données d'une table donnée
nommée « classe de persistance ».
 Un fichier de correspondance qui configure la correspondance entre la classe et la
table.
 Des propriétés de configuration, notamment des informations concernant la
connexion à la base de données.

L'architecture d'Hibernate

25/10/23 ENSAJ
Le fichier hibernate.properties sert à configurer l'accès à la base de données.

Les infos indispensables sont les suivantes :

 hibernate.connection.driver_class = Le chemin vers le driver JDBC,


 hibernate.connection.url = Le chemin d'accès à la base,
 hibernate.connection.username = Le nom d'utilisateur de la connexion,
 hibernate.connection.password = Le mot de passe de la connexion,
 hibernate.dialect = Le dialecte de votre base de données.

25/10/23 ENSAJ
Hibernate propose des classes qui héritent de la classe Dialect pour chaque base de
données supportée. C'est le nom de la classe correspondant à la base de
données utilisée qui doit être obligatoirement fourni à la propriété
hibernate.dialect.

Le fichier Hibernate.cfg.xml a presque la même utilité que le fichier


Hibernate.properties. Soit on configure la connexion JDBC dans le fichier
properties soit on le configure ici. Les deux cas sont équivalents.

La seule chose ou il change, est que ce fichier sert aussi à mapper les différents
fichiers de mapping de l'application.

25/10/23 ENSAJ
Une classe de données est un Javabean qui va encapsuler les
propriétés de la table dans ses champs private avec des
getters et setters et qui a un constructeur par défaut.

25/10/23 ENSAJ
La classe Hibernate nommée SessionFactory permet d’établir la connexion
avec la source de données à partir du fichier de configuration «
hibernate.cfg.xml ».On remarque que la classe SessionFactory serait
instanciée autant de fois qu'il y a de threads, il est donc plus adapté de
rendre une même instance de SessionFactory accessible par les threads.
Cette classe possède une méthode appelée currentSession() qui retourne
la session hibernate en cours si elle existe sinon elle se charge d’ouvrir
une nouvelle session .

25/10/23 ENSAJ
 Soit le diagramme de classe suivant :

 On souhaite développer une application de


gestion des machines.
25/10/23 ENSAJ
Objets métiers DAO SGBD

Java
Beans Tables
Data Access abstraction

Factory
DAO interface
Interfaces
DAO interface
create ()
delete ()
update ()
DAOs getAll ()
getById ()

25/10/23 ENSAJ
 Structure du projet

25/10/23 ENSAJ
@Entity
public class Machine {
@Id
@GeneratedValue
private int id;
private String marque;
private String reference;
private double prix;
@Temporal(javax.persistence.TemporalType.DATE)
private Date dateAchat;
@ManyToOne @Entity
private Salle salle; public class Salle {
public Machine() { @Id
salle = new Salle(); @GeneratedValue
} private int id;
//getters and setters private String code;
} private String libelle;
@OneToMany (mappedBy = "salle",fetch = FetchType. EAGER)
private List<Machine> machines;

public Salle() {
}
//getters and setters
}
25/10/23 ENSAJ
public interface IDao<T> {
boolean create(T o);
boolean update(T o);
boolean delete(T o);
T getById(int id);
List<T> getAll();
}

25/10/23 ENSAJ
MÉTHODE CREATE :
public boolean create(Salle o) {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(o);
session.getTransaction().commit();
return true; Vous devez gérer les
}
exceptions via un bloc
MÉTHODE UPDATE : try, catch et finally
public boolean update(Salle o) {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.update(o);
session.getTransaction().commit(); Vous devez gérer le type
return true; de retour selon le résultat
}
renvoyé par les méthodes
MÉTHODE DELETE : save, update…
public boolean delete(Salle o) {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.delete(o);
session.getTransaction().commit();
return true; Compléter la gestion
} des transactions
commit and rollback
25/10/23 ENSAJ
MÉTHODE GETBYID :

public Salle getById(int id) {


Salle salle = null;
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
salle = (Salle) session.get(Salle.class, id);
session.getTransaction().commit();
return salle;
}

MÉTHODE GETALL :
public List<Salle> getAll() {
List <Salle> salles = null;
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
salles = session.createQuery("from Salle").list();
session.getTransaction().commit();
return salles;
}

25/10/23 ENSAJ
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

25/10/23 ENSAJ
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/jsf7</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.connection.password">root</property>
<mapping class="ma.projet.beans.Machine"/>
<mapping class="ma.projet.beans.Salle"/>
</session-factory>
</hibernate-configuration> Déclaration des Entités

25/10/23 ENSAJ
public static void main(String[] args) {
SalleService ss = new SalleService();
//création des Salles
ss.create(new Salle("CC3", "Informatique"));
ss.create(new Salle("A1", "Arabe"));
ss.create(new Salle("A2", "Comptailité"));
//La liste des salles
for (Salle s : ss.getAll()) {
System.out.println("" + s.getCode());
}
}

25/10/23 ENSAJ
public static void main(String[] args) {
MachineService ms = new MachineService();
SalleService ss = new SalleService();
//Création des machines
ms.create(new Machine("HP", "HZ23", 5000, new Date(), ss.getById(1)));
ms.create(new Machine("HP", "HZ77", 4500, new Date(), ss.getById(1)));
ms.create(new Machine("TOSHIBA", "AZ34", 6000, new Date(), ss.getById(2)));
//Afficher les machines par salle
for(Salle s : ss.getAll()){
System.out.println("Salle : "+s.getCode());
for(Machine m : s.getMachines())
System.out.println("\t"+m.getReference());
}
}

Salle : CC3
HZ23
HZ77
Salle : A1
AZ34
Salle : A2

25/10/23 ENSAJ
Plusieurs stratégies existent, qui correspondent chacune à une
représentation différente dans le modèle relationnel de données.

25/10/23 ENSAJ
@Entity @Entity
@Inheritance(strategy = InheritanceType.JOINED) public class Employe extends Personne{
public class Personne { private double salaire;
@Id @Temporal(javax.persistence.TemporalType.DATE)
@GeneratedValue private Date dateEmb;
protected int id; public Employe() {
protected String nom; }
protected String prenom; //getters and setters
@Temporal(javax.persistence.TemporalType.DATE) …..
protected Date dateNaissance; }

public Personne() {
}
//getters and setters
…..
}

EmployeImpl ei = new EmployeImpl();


ei.create(new Employe("RAMI", "Saloua", new Date(), 1000, new Date()));

25/10/23 ENSAJ
@Entity @Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public class Employe extends Personne{
public class Personne { private double salaire;
@Id @Temporal(javax.persistence.TemporalType.DATE)
@GeneratedValue private Date dateEmb;
protected int id; public Employe() {
protected String nom; }
protected String prenom; //getters and setters
@Temporal(javax.persistence.TemporalType.DATE) …..
protected Date dateNaissance; }

public Personne() {
}
//getters and setters
…..
}

EmployeImpl ei = new EmployeImpl();


ei.create(new Employe("RAMI", "Saloua", new Date(), 1000, new Date()));

25/10/23 ENSAJ
@Entity @Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) public class Employe extends Personne{
public class Personne { private double salaire;
@Id @Temporal(javax.persistence.TemporalType.DATE)
@GeneratedValue private Date dateEmb;
protected int id; public Employe() {
protected String nom; }
protected String prenom; //getters and setters
@Temporal(javax.persistence.TemporalType.DATE) …..
protected Date dateNaissance; }

public Personne() {
}
//getters and setters
…..
}

EmployeImpl ei = new EmployeImpl();


ei.create(new Employe("RAMI", "Saloua", new Date(), 1000, new Date()));

25/10/23 ENSAJ
@Entity
public class Employe {
@Id
@GeneratedValue
private int id;
private String nom;
private String prenom;
@Temporal(javax.persistence.TemporalType.DATE)
private Date dateNaissance;
@ManyToMany(fetch = FetchType.EAGER)
private List<Service> services;

public Employe() {
}
@Entity getters and setters
public class Service { }
@Id
@GeneratedValue
private int id;
private String nom;
@ManyToMany(mappedBy = "services", fetch = FetchType.EAGER)
private List<Employe> employes;

public Service() {
}

getters and setters

} 25/10/23 ENSAJ
//Création d'un service
Service s = new Service();
s.setNom("Comp");
ServiceService ss = new ServiceService();
ss.create(s);

//Création d'un employé


EmployeService es = new EmployeService();
Employe e = new Employe();
e.setNom("safi");
e.setPrenom("ali");
e.setDateNaissance(new Date());
es.create(e);

//Affecter un employé dans un service


es.findById(1).getServices().add(ss.findById(1));
es.update(e);

25/10/23 ENSAJ
@Entity @Entity
public class Service { public class Employe {
@Id @Id
@GeneratedValue @GeneratedValue
private int id; private int id;
private String nom;
private String code;
private String prenom;
private String libelle; private String email;
@OneToMany(mappedBy = "service") @Temporal(javax.persistence.TemporalType.DATE)
private List<EmployeService> employeServices; private Date dateNaissance;
@OneToMany(mappedBy = "employe")
public Service() { private List<EmployeService> employeServices;
}
….. public Employe() {

}
@Embeddable
…..
public class EmployeServiceKey implements Serializable{
private int employe;
private int service;
private Date dateDebut;

public EmployeServiceKey() {
}

public EmployeServiceKey(int employe, int service, Date dateDebut) {


this.employe = employe;
@Entity
this.service = service;
public class EmployeService {
this.dateDebut = dateDebut;
} @EmbeddedId
private EmployeServiceKey id;
…. @JoinColumn(name = "employe", referencedColumnName = "id", insertable = false, updatable = false)
@ManyToOne
private Employe employe;
@JoinColumn(name = "service", referencedColumnName = "id", insertable = false, updatable = false)
@ManyToOne
private Service service;

public EmployeService() {
}
25/10/23 ENSAJ
 All Hibernate Annotations: Mapping Annotations
 Hibernate 5 - Using Stored Procedures for Querying
 Hibernate 5 - Persist Java 8 LocalDate, LocalDateTime and
Duration Example
 How to get query results as a Stream with Hibernate 5.2
 Hibernate 5 Named Query Tutorial with Examples

25/10/23 ENSAJ

Vous aimerez peut-être aussi