37
Riadh Ouersighni Année 2009-2010

Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Embed Size (px)

Citation preview

Page 1: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Riadh OuersighniAnnée 2009-2010

Page 2: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Architecture d'une application Java en couches

Une application java est souvent découpée en couches. Considérons une architecture courante, celle à trois couches :

La couche [1], (User Interface) : dialogue avec l'utilisateur, via une interface graphique Swing, une interface console ou une interface web. Elle a pour rôle de fournir des données provenant de l'utilisateur à la couche [2] ou bien de présenter à l'utilisateur des données fournies par la couche [2].

• La couche [2], appelée ici [metier] est la couche qui applique les règles dites métier, c.a.d. la logique spécifique de l'application, sans se préoccuper de savoir d'où viennent les données qu'on lui donne, ni où vont les résultats qu'elle produit.

• La couche [3], appelée ici [dao] (Data Access Object) est la couche qui fournit à la couche [2] des données pré-enregistrées et qui enregistre certains des résultats fournis par la couche [2].

Couche Interface

utilisateur

Couche MétierCouche d’accès

aux données (DAO)

Données

1 2 3

2Hibernate java

Page 3: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Couche accès aux données

Couche Interface

Couche Métier

Couche d’accès aux

données (DAO)

1 2 3

Couche JDBCutilisate

ur

Base de données

Il existe différentes possibilités pour implémenter la couche Accès aux Données

La couche [JDBC] est la couche standard utilisée en Java pour accéder à des bases de données. Elle isole la couche [dao] du SGBD qui gère la base de données.

3Hibernate java

Page 4: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

BDCouche

Hibernate

Objets image de la BD

Couche d’accès aux

données (DAO)

Couche JDBC

De multiples efforts ont été faits pour isoler la couche [dao] des aspects propriétaires des SGBD. Une solution qui a eu un vrai succès dans ce domaine ces dernières années, est celle d'Hibernate

La couche [Hibernate] vient se placer entre la couche [dao] écrite par le développeur et la couche [Jdbc]

Hibernate est un ORM (Object Relational Mapping), un outil qui fait le pont entre le modèle relationnel des bases de données et celui des objets manipulés par JavaLe développeur ne voit plus la couche [Jdbc] ni les tables de la BD. Il ne voit que l'image objet de BD, fournie par la couche [Hibernate]. Le pont entre les tables de la BD et les objets manipulés par la couche [dao] est fait par des fichiers de configuration de type XML

4

Couche HIBERNATE

Hibernate java

Page 5: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

HibernateHibernate est un projet open source visant à proposer un outil de mapping entre les objets et des données stockées dans une base de données relationnelle. Ce projet ne repose sur aucun standard mais il est très populaire notamment à cause de ses bonnes performances et de son ouverture avec de nombreuses bases de données.

Les bases de données supportées sont les principales du marché : Oracle, MySQL, PostgreSQL, Sybase, SQLServer, Sap DB, DB2,Interbase, ...

Le site officiel http://www.hibernate.org contient beaucoup d'informations sur l'outil et propose de le télécharger ainsi que sa documentation.

5Hibernate java

Page 6: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Architecture Hibernate

Hibernate java 6

Page 7: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

7Hibernate java

Nous allons utiliser Hibernate avec une base de données de type MySQL possédant une table nommée "personnes".

Hibernate a besoin de plusieurs éléments pour fonctionner :Une classe « javabean » qui encapsule les données d'une

occurrence d'une tableUn fichier de correspondance qui configure la

correspondance entre la classe et la tabledes propriétés de configuration notamment des informations

concernant la connexion à la base de données

Une fois ces éléments correctement définis, il est possible d'utiliser Hibernate dans le code des traitements à réaliser.

Principe de fonctionnement à l’aide d’un Exemple

Créez la table personnes dans la BD bdperso

Page 8: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Configuration Hibernate sous NetBeans 6.1 Sous Netbeans, ajoutez le framework Hibernate : Allez dans « tools “ + “plugins “+ “Available plugins” ,

sélectionnez Hibernate puis installez. Créez un nouveau projet web sous NetBeans Dans la définition du nouveau projet, cochez

Framework Hibernate Ajoutez Mysql jdbc Driver (click droit sur Librairie puis

Add) Configuration hibernate.cfg.xml : Pour exécuter Hibernate, il

faut lui fournir un certain nombre de propriétés concernant sa configuration pour qu'il puisse se connecter à la base de données. Ces propriétés peuvent être fournies sous plusieurs formes : un fichier de configuration nommé hibernate.properties et stocké dans

un répertoire inclus dans le classpath un fichier de configuration au format XML nommé

hibernate.cfg.xml

Hibernate java 8

Page 9: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 9

Page 10: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 10

Nom de la BD

Page 11: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Les propriétés de configuration

Les principales propriétés pour configurer la connexion JDBC sont :

Hibernate java 11

Nom Propriété Rôle

hibernate.connection.driver_class

nom pleinement qualifié de classe du pilote JDBC

hibernate.connection.url URL JDBC désignant la base de données

hibernate.connection.username

nom de l'utilisateur pour la connexion

hibernate.connection.password

mot de passe de l'utilisateur

hibernate.connection.pool_size

nombre maximum de connexions dans le poolAutres propriétés

Nom Propriété Rôle

hibernate.dialect nom de la classe pleinement qualifiée qui assure le dialogue avec la base de données

hibernate.show_sql booléen qui précise si les requêtes SQL générées par Hibernate sont affichées dans la console (utile lors du débogage)

Page 12: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 12

Le Fichier Hibernate.cfg.xml<?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration  DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  <hibernate-configuration>  <session-factory name="hiSession">  <!-- dialect -->  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>  <!-- driver -->  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  <!-- host -->  <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/bdperso </property>  <!-- username -->  <property name="hibernate.connection.username">root</property>  <!-- password to my db -->  <property name="hibernate.connection.password"/></property>  </session-factory>  </hibernate-configuration> 

Page 13: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Etape suivante : La création d'une classe qui va encapsuler les données

Cette classe doit respecter le standard des javabeans notamment encapsuler les propriétés dans ces champs private avec des getters et setters et avoir un constructeur vide.

Hibernate java 13

import java.util.Date;

public class Personnes { private Integer idPersonne; private String nomPersonne; private String prenomPersonne; private Date datenaissPersonne;

public Personnes(String nomPersonne, String prenomPersonne, Date datenaissPersonne) { this.nomPersonne = nomPersonne; this.prenomPersonne = prenomPersonne; this.datenaissPersonne = datenaissPersonne; } public Personnes() { }

Pour ajouter les Getters et les Setters : click droit puis choisir « Insert code » Netbeans génère automatiquement les méthodes get et set

Page 14: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 14

Clic droit ici

Page 15: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 15

Etape suivante : Mapping : La création d'un fichier de correspondance

Pour assurer le mapping, Hibernate a besoin d'un fichier de correspondance (mapping file) au format XML qui va contenir des informations sur la correspondance entre la classe définie et la table de la base de données.

Le plus simple est de définir un fichier de mapping par classe, nommé du nom de la classe suivi par ".hbm.xml".

Ce fichier doit être situé dans le même répertoire que la classe correspondante ou dans la même archive pour les applications packagées.

Dans notre projet Netbeans :

Click droit / new / other / hibernate / hibernate mapping file / OK

Différents éléments sont précisés dans ce document XML : la classe qui va encapsuler les données l'identifiant dans la base de données et son mode de génération le mapping entre les propriétés de classe et les champs de la base de données les relations

Page 16: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 16

Page 17: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 17

Page 18: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 18

Page 19: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 19

Page 20: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

<?xml version="1.0"?><!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

<class name="Personnes" table="personnes">

<id name="idPersonne" type="int" column="idpersonne">

<generator class="native"/>

</id>

<property name="nomPersonne" type="string" not-null="true" />

<property name="prenomPersonne" type="string" not-null="true" />

<property name="datenaissPersonne" type="date">

<meta attribute="field-description">date de naissance</meta>

</property>

</class>

</hibernate-mapping> Hibernate java 20

Page 21: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

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:

Hibernate java 21

Nom Obligatoire

rôle

name oui Nom de la classe

table oui Nom de la table dans la Base de donnée

dynamic-update

non booléen qui indique de ne mettre à jour que les champs dont la valeur a été modifiée (false par défaut)

dynamic-insert

non booléen qui indique de générer un ordre insert que pour les champs dont la valeur est non nulle (false par défaut)Le tag <generator>, fils obligatoire du tag <id>, permet de préciser quel

est le mode de génération d'un nouvel identifiant.

Ce tag possède un attribut : class (obligatoire) qui précise la classe qui va assurer la génération de la valeur d'un nouvel identifiant. Il existe plusieurs classes fournies en standard par Hibernate qui possèdent un nom utilisable comme valeur de cet attribut.

Page 22: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Les classes de génération fournies en standard par Hibernate possèdent chacun un nom :

Hibernate java 22

Nom Rôle

increment

incrémentation d'une valeur dans la JVM

identify utilisation d'un identifiant auto-incrémenté pour les bases de données qui le supportent (DB2, MySQL,SQL Server, ...)

sequence

utilisation d'une séquence pour les bases de données qui le supportent (Oracle, DB2, PostgreSQL, ...)

hilo utilisation d'un algorithme qui utilise une valeur réservée pour une table d'une base de données (par exemple une table qui stocke la valeur du prochain identifiant pour chaque table)

seqhilo idem mais avec un mécanisme proche d'une séquence

uuid.hex utilisation d'un algorithme générant un identifiant sur 32 caractères prenant en compte entre autre l'adresse IP de la machine et l'heure du système

uuid.string

idem générant un identifiant sur 16 caractères

native utilise la meilleure solution proposée par la base de données

assigned la valeur est fournie par l'application

foreign la valeur est fournie par un autre objet avec lequel la classe est associée

Page 23: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 23

Hibernate doit savoir qu’est ce qu’il “mappe” Ajouter ce code au fichier xml “hibernate.cfg.xml”

<mapping class=“Personnes"  resource=“Personnes.hbm.xml"/>   

Page 24: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 24

Utilisation d'Hibernate

Pour utiliser Hibernate dans le code, il est nécessaire de réaliser plusieurs opérations :

création d'une instance de la classecréation d'une instance de la classe SessionFactorycréation d'une instance de la classe Session qui va permettre

d'utiliser les services d'Hibernate

Page 25: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 25

Si les propriétés sont définies dans le fichier hibernate.properties, il faut tout d'abord créer une instance de la classe Configuration. Pour lui associer la ou les classes encapsulant les données, la classe propose deux méthodes :

1.addFile() qui attend en paramètre le nom du fichier de mapping

2.addClass() qui attend en paramètre un objet de type Class encapsulant la classe. Dans ce cas, la méthode va rechercher un fichier nommé nom_de_la_classe.hbm.xml dans le classpath (ce fichier doit se situé dans le même répertoire que le fichier .class de la classe correspondante)

Page 26: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 26

Une instance de la classe Session est obtenu à partir d'une fabrique de type SessionFactory.

Cet objet est obtenu à partir de l'instance du type Configuration en utilisant la méthode buildSessionFactory().

La méthode openSession() de la classe SessionFactory permet d'obtenir une instance de la classe Session.

Par défaut, la méthode openSession() qui va ouvrir une connexion vers la base de données en utilisant les informationsfournies par les propriétés de configuration.

Page 27: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 27

Exemple :

import net.sf.hibernate.*;import net.sf.hibernate.cfg.Configuration;import java.util.Date;public class TestHibernate1 {

public static void main(String args[]) throws Exception {Configuration config = new Configuration();config.addClass(Personnes.class);SessionFactory sessionFactory =

config.buildSessionFactory();Session session = sessionFactory.openSession();

….

Page 28: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 28

Le fichier “HibernateUtil.java” permet de créer le “session factory “ . Il faut créer une nouvelle classe

import org.hibernate.SessionFactory;  import org.hibernate.cfg.Configuration;    public class HibernateUtil {    private static final SessionFactory sessionFactory;  static {  try {    //Create the SessionFactory  sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();  } catch (Throwable ex) {  // Log the Exception  System.err.println("SessionFactory creation failed!!!" + ex);  throw new ExceptionInInitializerError(ex);  }  }  public static SessionFactory getSessionFactory() {  return sessionFactory;  }  } 

Page 29: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 29

La persistance d'une nouvelle occurrence

Pour créer une nouvelle occurrence dans la source de données, il suffit de :

créer une nouvelle instance de classe encapsulant les données, de valoriser ces propriétés et d'appeler la méthode save() de la session en lui passant en paramètre l'objet encapsulant les données.

La méthode save() n'a aucune action directe sur la base de données. Pour enregistrer les données dans la base, il fautréaliser un commit sur la connexion ou la transaction ou faire appel à la méthode flush() de la classe Session.

Voir exemple de code suivant :

Page 30: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 30

import net.sf.hibernate.*;import net.sf.hibernate.cfg.Configuration;import java.util.Date;public class TestHibernate1 {public static void main(String args[]) throws Exception {Configuration config = new Configuration();config.addClass(Personnes.class);SessionFactory sessionFactory = config.buildSessionFactory();Session session = sessionFactory.openSession();Transaction tx = null;try { tx = session.beginTransaction(); Personnes personne = new Personnes("nom3", "prenom3", new Date()); session.save(personne); session.flush() ; tx.commit();} catch (Exception e) {

if (tx != null) { tx.rollback();}throw e;} finally { session.close();}sessionFactory.close();}}

Page 31: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 31

Le langage de requête HQL

Pour offrir un langage d'interrogation commun à toutes les base de données, Hibernate propose son propre langagenommé HQL (Hibernate Query Language)

HQL est proche de SQL avec une utilisation sous forme d'objets des noms de certaines entités : il n'y a aucune référence aux tables ou aux champs car ceux ci sont référencés respectivement par leur classe et leurs propriétés.

C'est Hibernate qui se charge de générer la requête SQL à partir de la requête HQL en tenant compte du contexte (type de base de données utilisée défini dans le fichier de configuration et la configuration du mapping).

Page 32: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 32

La méthode find() de la classe Session permet d'effectuer une recherche d'occurrences grâce à la requête fournie en paramètre.

Exemple : rechercher toutes les occurrences d'une table

import net.sf.hibernate.*;import net.sf.hibernate.cfg.Configuration;import java.util.*;public class TestHibernate3 { public static void main(String args[]) throws Exception { Configuration config = new Configuration(); config.addClass(Personnes.class); SessionFactory sessionFactory = config.buildSessionFactory(); Session session = sessionFactory.openSession(); try { List personnes = session.find("from Personnes"); for (int i = 0; i < personnes.size(); i++) { Personnes personne = (Personnes) personnes.get(i); System.out.println("nom = " + personne.getNomPersonne()); } } finally { session.close();}sessionFactory.close();}}

Page 33: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 33

import net.sf.hibernate.*;import net.sf.hibernate.cfg.Configuration;import java.util.*;public class TestHibernate4 { public static void main(String args[]) throws Exception { Configuration config = new Configuration(); config.addClass(Personnes.class); SessionFactory sessionFactory = config.buildSessionFactory(); Session session = sessionFactory.openSession(); try { List personnes = session.find("from Personnes p where p.nomPersonne=?","nom1", Hibernate.STRING); for (int i = 0; i < personnes.size(); i++) { Personnes personne = (Personnes) personnes.get(i); System.out.println("nom = " + personne.getNomPersonne()); }} finally {session.close();}sessionFactory.close();}}

Page 34: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 34

import net.sf.hibernate.*;import net.sf.hibernate.cfg.Configuration;import java.util.*;

public class TestHibernate5 { public static void main(String args[]) throws Exception { Configuration config = new Configuration(); config.addClass(Personnes.class); SessionFactory sessionFactory = config.buildSessionFactory(); Session session = sessionFactory.openSession(); try { int compteur = ( (Integer) session.iterate("select count(*) from Personnes").next()).intValue();

System.out.println("compteur = " + compteur); } finally {session.close();sessionFactory.close();}}}

Page 35: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 35

La mise à jour d'une occurrence

Pour mettre à jour une occurrence dans la source de données, il suffit d'appeler la méthode update() de la session en luipassant en paramètre l'objet encapsulant les données.

Le mode de fonctionnement de cette méthode est similaire à celui de la méthode save().

La méthode saveOrUpdate() laisse Hibernate choisir entre l'utilisation de la méthode save() ou update() en fonction de lavaleur de l'identifiant dans la classe encapsulant les données.

Page 36: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 36

La suppression d'une ou plusieurs occurrences

La méthode delete() de la classe Session permet de supprimer une ou plusieurs occurrences en fonction de la version surchargée de la méthode utilisée.

Pour supprimer une occurrence encapsulée dans une classe, il suffit d'invoquer la classe en lui passant en paramètrel'instance de la classe.

Pour supprimer plusieurs occurrences, voire toutes, il faut passer en paramètre de la méthode delete(), une chaîne decaractères contenant la requête HQL pour préciser les éléments concernés par la suppression.

Exemple session.delete("from Personnes");

Page 37: Riadh Ouersighni Année 2009-2010. Architecture d'une application Java en couches Une application java est souvent découpée en couches. Considérons une

Hibernate java 37

Les relations

Un des fondements du modèle de données relationnelles repose sur les relations qui peuvent intervenir entre une table et une ou plusieurs autres tables ou la table elle même.

Hibernate propose de transcrire ces relations du modèle relationnel dans le modèle objet. Il supporte plusieurs types derelations :

•relation de type 1 - 1 (one-to-one)•relation de type 1 - n (many-to-one)•relation de type n - n (many-to-many)

Dans le fichier de mapping, il est nécessaire de définir les relations entre la table concernée et les tables avec lesquelleselle possède des relations.