0
Author: Thibault Cuvillier – Creative Commons 2.0

Java Persistence API

Auteur: Thibault Cuvillier
Consultant indépendant...
Contenu de la présentation
•
•
•
•
•
•

Chap
Chap
Chap
Chap
Chap
Chap

1:
2:
3:
4:
5:
6:

Introduction
Mapping objet relat...
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

Introduction

JP 1.1 - Template 1.0
Introduction à javax.persistence
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé
...
Accéder à la base de données
Session Http
• Les objets d'une application
1
peuvent être:
*
– Transitoires: ils ne surviven...
Les quatre modèles 1/2
transitoire

Le modèle conceptuel
La compréhension de l'utilisateur

Le modèle logique
Modèle objet...
Les quatre modèles 2/2
• Les quatre modèles doivent être isomorphes
– Intégration sémantique
• Les relations entre les mod...
Le mapping objet-relationnel
• Décrit la projection d'une classe dans un SGRBR
• Exemple:
– Une classe = Une table
– Une p...
API de persistance avec JDBC / DAO 1/2
• Les objets persistants sont des JavaBeans
• Vous y accédez via des DAO
– Data Acc...
API de persistance avec JDBC/DAO 2/2
• La couche de persistance prend en charge le
mapping O/R
– Hard-codé en Java, Séparé...
Cache de persistance
• L'ajout d'un cache permet:
– De limiter le nombre de requêtes SQL
– De ne conserver en mémoire qu'u...
Cache transactionnel
• Le cache doit être transactionnel
– Isolation transactionnelle
– Consistance
• Il doit être multi-t...
Outils de mapping O/R
• Moteur de mapping générique
– utilise une description du mapping
• Cache transactionnel
• Les obje...
Mapping objet relationnel
• Produits de mapping objet / relationnels
– Hibernate, JDO, Toplink (Oracle)
• Ces produits sav...
Exemple Hibernate 1/2
Client.hbm.xml
<hibernate-mapping>
<<Entity>>
Client
id
prénom
nom
téléphone

POJO

<class name="com...
Exemple Hibernate 2/2
• Le code client devient simple et naturel:
Session session = … ouvrir la session Hibernate …;
Trans...
javax.persistence
• Nouvelle API Java de persistance
– Implémentations avec Hibernate, JDO, Toplink ou autre
– J2EE (modul...
Entités
• Interface unifiée
• Le descripteur de mapping O/R standard
– Peut être généré à partir d'annotations Java5.
@Ent...
Cycle de vie des Entités
• Gérée = associée à un contexte de
persistance
Etat
Dans la base
Associé à un contexte
de persis...
Avantages des Entités
• Objets persistants de faible granularité
– Plus proche du modèle d'analyse
• Mapping O/R puissant
...
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

Mapping Objet / Relationnel
Niveau 1
JP 1.1 - Templa...
Mapping OR
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Cr...
Mapping O/R > Mapping simple
• Mapping O/R
Mapping simple
Identité simple
Callback

Thibault Cuvillier
Creative Commons 2....
Classe persistante
• Doit être annotée avec @Entity
@Entity(name="Compte"
access=AccessType.PROPERTY)

– name
Nom de l'ent...
Mapping 1 classe / 1 table 1/3
• Annotation @Table
– name : Nom de la table, nom de la classe.
– catalog : Catalogue de la...
Mapping 1 classe / 1 table 2/3
• Table: <schéma par
défaut>.Client
• Table: <schéma par
défaut>.CLIENT_TBL

• Table: FORMA...
Mapping 1 classe / 1 table 3/3
• Table FORMATION.CLIENT_TBL + contrainte
d'unicité sur (prenom, nom) et (telephone)
@Entit...
Propriétés persistantes 1/2
• Doit avoir un des types suivants:
– Type primaire Java: int, long, double …
– String, BigInt...
Propriétés persistantes 2/2
• Déclarez les accesseurs public:
– T getX() et void setX(T t)
– boolean isX() et void setX(bo...
@Basic, @Temporal
• Indique un mapping simple pour une propriété
persistante
– Par défaut, toutes les propriétés sont pers...
Mapping 1 propriété / 1 colonne 1/3
• Utilisez l'annotation @Column
– name: Nom de la colonne - Nom de la propriété
– inse...
Mapping 1 propriété / 1 colonne 1/3
• Colonne "NOM"
VARCHAR(255)

private String _nom;
public String getNom() { return _no...
Mapping 1 propriété / 1 colonne 3/3
• Colonne "DESC"
CLOB

private String _desc;
@Column(columnDescription="CLOB")
public ...
Mapping O/R > Identité simple
• Mapping O/R
Mapping simple
Identité simple
Callback

Thibault Cuvillier
Creative Commons 2...
Identité
• L'identité d'une Entité = Clef Primaire
• Identité métier:
– Identité simple = Une seule valeur
– Identité comp...
Recommandations
• N'utilisez que des Identificateurs neutres
– Long ou long
– Initialisation: séquence, table de compteurs...
Identité simple 1/4
• La propriété contenant l'identité: @Id
• Pour une identité technique générée:
• @GeneratedValue
– st...
Identité simple 2/4
• La valeur de l'ID
est contrôlée par
l'application

@Id
public long getId() { return _id; }

@Id

• L...
Identité simple 3/4
• Les ID sont générés
à partir de la table
IDGEN possédant
une colonne
ID_KEY (PK),
ID_VAL.
• La valeu...
Identité simple 4/4
• La valeur de l'ID est générée par la base, par
une colonne à incrémentation automatique
• Colonne Au...
Mapping O/R > Callbacks
• Mapping O/R
Mapping simple
Identité simple
Callback

Thibault Cuvillier
Creative Commons 2.0

ja...
Callbacks
• Méthodes déclenchées
pour notifier les
changements d'états
d'une entité

@Entity
public class Login {
private ...
Callbacks des entités
• @PrePersist et @PostPersist
– Appelé avant et après EntityManager.persist()
• @PreRemove et @PostR...
Listener d'entité
• Vous pouvez mettre le code des callbacks dans
un listener avec @EntityListener.
Personne.java
@Entity
...
Travaux pratiques
• Ouvrez le projet JP-Lab01-Mapping-Question
– Suivez les instructions

Thibault Cuvillier
Creative Comm...
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

EntityManager

JP 1.1 - Template 1.0
EntityManager
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier...
EntityManager
• Permet de changer l'état persistant des entités
– Création, destruction, modification
• Associé à un conte...
Création d'un EntityManager avec J2SE
Attention, différent pour
• L'EntityManager est créé par une
un serveur J2EE
factory...
persistence.xml
• La factory est décrite dans le fichier
Transactions:
META-INF/persistence.xml
•RESOURCE_LOCAL
•JTA

<?xm...
TRANSACTION et EXTENDED 1/2
• Le contexte de persistance maintient les données
en cache.
• Le cache peut avoir deux durées...
TRANSACTION et EXTENDED 2/2
• Pour créer un EntityManager EXTENDED:
EntityManagerFactory factory = Persistence.createEntit...
EntityManager.find
• EntityManager.find(Class c, Object id)

– Charge un objet en mémoire et le retourne
• EntityManager.g...
Gérer les transactions
EntityManager em = …;
• Pas de transactions
EntityTransaction tx =
imbriquées
em.getTransaction();
...
EntityManager.persist 1/2
• void persist(Object entity)
Etat

Action

Transitoire Insertion dans la base (1)
Géré

Rien su...
EntityManager.persist 2/2
• Exemple:
EntityManager em = …;
EntityTransaction tx = em.getTransaction();
tx.begin();
Client ...
EntityManager.remove
• void remove(Object entity)
Etat

Action

Transitoire

Rien sur l'entité, mais cascade (1)

Géré

De...
EntityManager.merge
• <T> T merge(T entity)
– Retourne une nouvel
entité géré

!

Attention, avec Hibernate,
provoque une ...
EntityManager.merge: exemple
• La méthode fetch retourne l'objet persistant et le rend
détache du contexte de persistance....
Objets détachés
• Un objet persistant devient détaché quand:
– Le contexte de persistance se termine:
• TRANSACTION: Fin d...
Transactions optimistes 1/2
• Un objet peut être modifié entre sa lecture et son
merge par une autre requête
– La dernière...
Transactions optimistes 2/2
• Il faut identifier la propriété contenant le numéro
de version avec @Version
– Peut être du ...
Mise à jour de la base de données
• La base de donnée est mise à jour lors du commit
ou avant l'exécution d'une query
• Po...
Travaux pratiques
• Ouvrez le projet JP-Lab02-EntityManagerQuestion
– Suivez les instructions

Thibault Cuvillier
Creative...
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

EJBQL
Niveau 1
JP 1.1 - Template 1.0
EJBQL
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creativ...
Queries EJBQL simples
• EJBQL permet d'exécuter des requêtes
– Pour lire des données
– De faire des UPDATE et DELETE en ma...
La clause SELECT
• SELECT c from Client c
– Retourne tous les clients
• SELECT c.name, c.email from Client c
– Retourne le...
DISTINCT, ORDER BY, NEW
• Select DISTINCT c.name from Client c
– Retourne une liste de nom unique
• Select c from Client c...
Opérateurs de la clause WHERE 1/2
• [NOT] BETWEEN
– WHERE c.age BETWEEN 0 and 17
– Equivalent à: c.age >= 0 AND c.age <= 1...
Fonctions EJBQL
• CONCAT("a", "b") => "ab"
• TRIM([BOTH, " ", ]" a ") => "a"

– 1er argument: BOTH, LEADING, TRAILING
•
•
...
Opérateurs de la clause WHERE 3
• EXISTS
– Vrai si la sous-requête retourne au moins un objet
SELECT DISTINCT emp FROM Emp...
GROUP BY
• GROUP BY permet de regrouper
les valeurs retournées par
la requête
• Requête sans clause GROUP BY:

Entreprise
...
HAVING
• Permet de tester des valeurs agrégées
– Impossible dans une clause WHERE
select v.entreprise, SUM(v.montant)
from...
DELETE et UPDATE
• Permet de déclencher des delete et update de
masse dans un batch.
• DELETE:
• UPDATE:

delete from Clie...
Exécuter une requête simples
• Les requêtes simples
public List findClients(EntityManager em) {
Query query = em.createQue...
Requêtes nommées
• Déclarer les requêtes dans une annotation
@NamedQueries(
@NamedQuery(
name="getByName",
query="select e...
Utiliser le SQL natif
• Vous pouvez utiliser des requêtes SQL
public List getClients() {
Query query = _em.createNativeQue...
Mapping d'un ResultSet
• Vous pouvez mapper chaque colonne sur une ou
plusieurs classes
– Pas forcément des entités
@SqlRe...
Travaux pratiques
• Ouvrez le projet JP-Lab03-EJBQL-Question
– Suivez les instructions

Thibault Cuvillier
Creative Common...
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

Mapping O/R
Niveau 2
JP 1.1 - Template 1.0
Mapping avancé
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillie...
Mapping des relations
Mapping avancé
Mapping des relations
Mapping de l'héritage
Autres mappings

Thibault Cuvillier
Creat...
Relations entre Entités
• Support des relations 1-1, 1-n, n-m
• Les relations peuvent uni ou bidirectionnelles
• Certaines...
Relation 1-1
Map sur la table PERSONNE
Propriétaire de la relation
@Entity
public class Personne {
private long _id;
priva...
Annotation OneToOne
• @OneToOne
– (O) String mappedBy = ""
Propriété propriétaire de la relation
– (O) boolean optional = ...
Fetch des entités
• EAGER:
– Les objets liés sont chargés en une seule requête SQL
1 find(Personne.class, id)
2 getLogin()...
Relation 1-n
Map sur la table LOGIN
Propriétaire de la relation

@Entity
public class Login {
private long _id;
private Ro...
Intégrité des relations
• C'est au développeur d'assurer l'intégrité des
relations
– Positionner la relation inverse Login...
Annotations ManyToOne et OneToMany
• ManyToOne: même attributs que OneToOne
• OneToMany: même attributs que OneToOne
– Sau...
Relation n-m
Map sur la table ROLE
Propriétaire de la relation

@Entity
public class Role {
private long _id;
private List...
Mapping d'une clé étrangère 1/2
Jointure
composite
Jointure
simple

@Entity
public class Login {
private long _id;
private...
Mapping d'une clé étrangère 2/2
• @JoinColumn
– (O) String name
Nom de la colonne contenant la clef étrangère.
Par défaut:...
Mapping d'une table d'association
• @JoinTable permet de préciser le nom de la table
d'association
@ManyToOne
@JoinTable(
...
Mapper une HashMap
• Permet de mapper la valeur des clefs d'une Map
– @MapKey: name contient le nom de la propriété
persis...
Ordre des relations
• Permet d'ordonner les
objets liés en fonction
d'un ou plusieurs
propriétés.
• @OrderBy
– Par défaut:...
BLOB et CLOB
• Permet de préciser le type d'une colonne
contenant un Large OBject
@Entity
– Propriété String
public class ...
Travaux pratiques
• Ouvrez le projet JP-Lab04-Relation-Question
– Suivez les instructions

Thibault Cuvillier
Creative Com...
Mapping de l'héritage
Mapping avancé
Mapping des relations
Mapping de l'héritage
Autres mappings

Thibault Cuvillier
Creat...
Héritage
• Une entité peut hériter d'une autre entité
– Héritage des propriétés
– Héritage des relations
– Requêtes EJBQL ...
Une table par hiérarchie
• Une colonne donne le
type de l'objet:
– Le discriminant
• Requête polymorphe:
– select v from V...
Une table par hiérarchie: exemple
@Entity
@Inheritance(
strategy=SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=STRI...
Une table par classe concrète
• Consomme peu de place
disque
• Requêtes polymorphes
coûteuses

Voiture
id
couleur

proprié...
Une table par classe concrète: exemple
@Entity
@Inheritance(strategy=TABLE_PER_CLASS)
public abstract class Voiture {
@Id ...
Une table par classe
• Proche du modèle objet
• Performance des
requêtes

Voiture
id
couleur

propriétaire
0..n

Personne
...
Une table par classe: exemple
@Entity
@Inheritance(strategy=JOINED
)
public abstract class Voiture {
@Id long _id;
private...
Travaux pratiques
• Ouvrez le projet JP-Lab05-Inheritance-Question
– Suivez les instructions

Thibault Cuvillier
Creative ...
Autres mappings
Mapping avancé
Mapping des relations
Mapping de l'héritage
Autres mappings

Thibault Cuvillier
Creative Co...
Les classes embedded
• Classe Java contenant une partie de l'état de
l'entité
@Embeddable
public class Adresse {
– Toujour...
Super classe mappées
• Factorise des mapping communs entre classes
• Pas d'annotation pour
contrôler l'héritage
– La super...
Identité composite 1/2
• L'identité d'une Entité peut être encapsulé dans
une classe
– Bonne pratique: pourquoi ?
• Deux s...
Identité composite 2/2
• Chaque propriété de l'identificateur map sur une
propriété de l'entité
@Entity
@IdClass(ClientID....
Mapper une classe sur plusieurs tables
@Entity
@Table(name="PERSONNE")
@SecondaryTable(
name="PERSONNE_DETAILS",
pkJoinCol...
Travaux pratiques
• Ouvrez le projet JP-Lab06-Embedded-Question
– Suivez les instructions

Thibault Cuvillier
Creative Com...
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

EJBQL
Niveau 2
JP 1.1 - Template 1.0
EJBQL avancé
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
...
Opérateurs sur les relations
• IN(<Relation ToMany>)
– Jointure entre deux entités
– select c from Commande c, IN(c.lignes...
Les jointures SQL
• Un JOIN permet de combiner les lignes de
plusieurs tables
• Deux types de jointures EJBQL:
– [INNER] J...
INNER Join
• Ne retourne pas les valeurs nulles de l'entité
jointe
– Il n'y a pas Sophie Fonfec dans le résultat !
• selec...
LEFT OUTER JOIN
• Retourne aussi les valeurs null de l'entité jointe
• select c.nom, p.nom
from Client c LEFT OUTER JOIN c...
FETCH
• select p from Produit p JOIN p.client c
– Lit les clients et produits en trois requêtes
select p from Produit p JO...
Sous-requêtes EJBQL
• Une requête peut contenir une sous-requête
SELECT c FROM Customer c WHERE (
SELECT COUNT(o) FROM c.o...
Travaux pratiques
• Ouvrez le projet JP-Lab07-EJBQL2-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commo...
Upcoming SlideShare
Loading in...5
×

Formation JPA Java persistence API

1,153

Published on

Support de formation Java Persistence API pour développeurs Java.

Contenu:
Chap 1: Introduction
Chap 2: Mapping objet relationnel – Niveau 1
Chap 3: EntityManager
Chap 4: EJBQL – Niveau 1
Chap 5: Mapping objet relationnel – Niveau 2
Chap 6: EJBQL – Niveau 2

Enjoy.

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

  • Be the first to like this

No Downloads
Views
Total Views
1,153
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
92
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Formation JPA Java persistence API"

  1. 1. Author: Thibault Cuvillier – Creative Commons 2.0 Java Persistence API Auteur: Thibault Cuvillier Consultant indépendant cuvillier@gmail.com http://www.btcweb.com JP 1.1 - Template 1.0
  2. 2. Contenu de la présentation • • • • • • Chap Chap Chap Chap Chap Chap 1: 2: 3: 4: 5: 6: Introduction Mapping objet relationnel – Niveau 1 EntityManager EJBQL – Niveau 1 Mapping objet relationnel – Niveau 2 EJBQL – Niveau 2 • Les questions et corrigés des TP sont accessibles sur mon site. • JPA 1, TP avec Hibernate 3.1 et Eclipse (pas mavenifié…) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 2
  3. 3. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence Introduction JP 1.1 - Template 1.0
  4. 4. Introduction à javax.persistence Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 4
  5. 5. Accéder à la base de données Session Http • Les objets d'une application 1 peuvent être: * – Transitoires: ils ne survivent pas Caddie 1 à l'application * – Persistants: ils survivent à l'application Item 1 • Exemple: dans un système de * vente en ligne: Produit – La classe Caddie est transitoire, ne contenant que des informations sur la session – La classe produit est persistante dans une base de données. Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 5
  6. 6. Les quatre modèles 1/2 transitoire Le modèle conceptuel La compréhension de l'utilisateur Le modèle logique Modèle objet Le modèle de présentation Les données présentées à l'utilisateur Thibault Cuvillier Creative Commons 2.0 Le modèle physique Schéma de la base javax.persistence / Introduction 6
  7. 7. Les quatre modèles 2/2 • Les quatre modèles doivent être isomorphes – Intégration sémantique • Les relations entre les modèles sont des mappings • Mapping entre le modèle logique et le schéma d'une base de données relationnelle: – Mapping Objet Relationnel Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 7
  8. 8. Le mapping objet-relationnel • Décrit la projection d'une classe dans un SGRBR • Exemple: – Une classe = Une table – Une propriété = Une colonne • Le mapping O/R est plus complique: – Comment projeter l'héritage ? – Comment projeter les relations entre objets ? – Comment projeter les types de données Java ? –… Suite • Il y a de nombreuses conceptions possibles… Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 8
  9. 9. API de persistance avec JDBC / DAO 1/2 • Les objets persistants sont des JavaBeans • Vous y accédez via des DAO – Data Access Object • Implémente les méthodes de persistance: – Insérer, détruire, modifier, requêtes… PersonneDAO Personne prenom nom email Thibault Cuvillier Creative Commons 2.0 inserer détruire modifier requete(prenom, nom) javax.persistence / Introduction 9
  10. 10. API de persistance avec JDBC/DAO 2/2 • La couche de persistance prend en charge le mapping O/R – Hard-codé en Java, Séparé des données Application Persistance POJO Mapping O/R • Mais: – Un objet peut être chargé deux fois en mémoire – La navigation entre objets est délicate à gérer – Les objets ne sont stockés en cache, générant un flux important de requêtes SQL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 10
  11. 11. Cache de persistance • L'ajout d'un cache permet: – De limiter le nombre de requêtes SQL – De ne conserver en mémoire qu'un seul exemplaire des objets persistants Application Persistance POJO Cache Mapping O/R • Mais, comment gérer les transactions ? Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 11
  12. 12. Cache transactionnel • Le cache doit être transactionnel – Isolation transactionnelle – Consistance • Il doit être multi-thread safe Persistance POJO Application Cache Mapping O/R Gestion des transactions Gestion de la sécurité • Cette solution est complexe Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 12
  13. 13. Outils de mapping O/R • Moteur de mapping générique – utilise une description du mapping • Cache transactionnel • Les objets persistants sont des POJOs • Un DAO générique mapping.xml Description du mapping O/R Persistance API Application Cache Mapping O/R Gestion des transactions Gestion de la sécurité Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 13
  14. 14. Mapping objet relationnel • Produits de mapping objet / relationnels – Hibernate, JDO, Toplink (Oracle) • Ces produits savent: – Mapper une classe sur plusieurs tables, – Mapper des objets dépendants, – Mapper types complexes, – Mapper des relations, – Mapper l'héritage entre entités, – Gérer des caches locaux ou distribués. Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 14
  15. 15. Exemple Hibernate 1/2 Client.hbm.xml <hibernate-mapping> <<Entity>> Client id prénom nom téléphone POJO <class name="com.btc.Client" table="CLIENT"> <property name="prénom"> <column name="PRENOM" length="32"/> </property> … </class> </hibernate-mapping> Mapping O/R <<Tables>> CLIENT ID PRENOM NOM TELEPHONE RUE 1 Adresse rue ville codePostal <<Table>> EMAIL 0..* EMail email Thibault Cuvillier Creative Commons 2.0 CLIENT_FK EMAIL javax.persistence / Introduction VILLE CODEPOSTAL Tables 15
  16. 16. Exemple Hibernate 2/2 • Le code client devient simple et naturel: Session session = … ouvrir la session Hibernate …; Transaction tx = session.beginTransaction(); tx.begin(); Client client = new Client(); client.setPrénom("Bill"); client.setNom("Gates"); Adresse adresse = new Adresse("5 rue de l'église", "Lyon", "69002"); client.setAdresse(addresse); client.addEMail("bill@microsoft.com"); client.addEMail("bilou@microsoft.com"); session.save(client); tx.commit(); session.close(); Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 16
  17. 17. javax.persistence • Nouvelle API Java de persistance – Implémentations avec Hibernate, JDO, Toplink ou autre – J2EE (module EJB ou Web) ou J2SE • package javax.persistence PersistenceContext – Fonctionne avec J2SE et J2EE PersistenceContext • Contexte de persistance: – Gère le cache des objets PersistenceContext – Transactionnel – Durée de vie: TRANSACTION ou EXTENDED – Une application peut utiliser plusieurs contextes Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 17
  18. 18. Entités • Interface unifiée • Le descripteur de mapping O/R standard – Peut être généré à partir d'annotations Java5. @Entity public class Client extends Serializable { private long _id; private String _nom; @Id public long getId() { return _id; } public void setId(long id) { _id = id; } public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } … } Cette entité est complète ! Mapping par défaut <<Tables>> CLIENT ID NOM Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 18
  19. 19. Cycle de vie des Entités • Gérée = associée à un contexte de persistance Etat Dans la base Associé à un contexte de persistance Transitoire Non Non Existe Oui Oui Détaché Oui Non Détruit Non Oui Non Géré Transitoire Détaché Thibault Cuvillier Creative Commons 2.0 Géré dans un contexte persist cascade merge Existe find query EJBQL persist Détruit sérialisation fin de TX javax.persistence / Introduction 19
  20. 20. Avantages des Entités • Objets persistants de faible granularité – Plus proche du modèle d'analyse • Mapping O/R puissant • Fonctionne avec J2EE et J2SE • Langage de Query: EJBQL • Accès direct à la connexion sous jacente – Pour optimisations – Pour utiliser des API spécifiques (Hibernate, JDO) • Permet de générer le schéma de la base à partir des annotations (pas recommandé) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 20
  21. 21. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence Mapping Objet / Relationnel Niveau 1 JP 1.1 - Template 1.0
  22. 22. Mapping OR Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 22
  23. 23. Mapping O/R > Mapping simple • Mapping O/R Mapping simple Identité simple Callback Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 23
  24. 24. Classe persistante • Doit être annotée avec @Entity @Entity(name="Compte" access=AccessType.PROPERTY) – name Nom de l'entité utilisé dans les expressions EJBQL select c from Compte c where c.solde < 0 – access Annotation des attributs persistants sur le getter (PROPERTY, par défaut) ou sur les attributs (FIELD) qui ne doivent pas être privés (à éviter!). • Doit avoir un constructeur par défaut Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 24
  25. 25. Mapping 1 classe / 1 table 1/3 • Annotation @Table – name : Nom de la table, nom de la classe. – catalog : Catalogue de la table, celui de la ctx. – schema: Schéma de la table, celui de la ctx. • Pour générer le schéma: – UniqueContraint uniqueContraints[] Contraintes d'unicité simples ou composites – Annotation @UniqueContraint • columnNames: colonnes dans la contrainte Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 25
  26. 26. Mapping 1 classe / 1 table 2/3 • Table: <schéma par défaut>.Client • Table: <schéma par défaut>.CLIENT_TBL • Table: FORMATION. CLIENT_TBL Thibault Cuvillier Creative Commons 2.0 @Entity public class Client implements Serializable { … } @Entity @Table(name="CLIENT_TBL") public class Client implements Serializable { … } @Entity @Table(name="CLIENT_TBL", schema="FORMATION") public class Client implements Serializable { … } javax.persistence / Introduction 26
  27. 27. Mapping 1 classe / 1 table 3/3 • Table FORMATION.CLIENT_TBL + contrainte d'unicité sur (prenom, nom) et (telephone) @Entity @Table( name="CLIENT_TBL", uniqueConstraints={ @UniqueConstraint(columnNames={"nom", "prenom"}), @UniqueConstraint(columnNames={"telephone"})} ) public class Client implements Serializable { … } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 27
  28. 28. Propriétés persistantes 1/2 • Doit avoir un des types suivants: – Type primaire Java: int, long, double … – String, BigInteger, BigDecimal, Date, Calendar, Date… – byte[], Byte[], char[], Character[] – enums Java5 (colonne integer ou String) – Classe Java sérializable (a éviter, voir + loin) – Classe Java dépendante (voir + loin) – Collection, Set, List, Map ou génériques List<T>… • Type de base, Entités. – Attention, les types de base ne peuvent être NULL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 28
  29. 29. Propriétés persistantes 2/2 • Déclarez les accesseurs public: – T getX() et void setX(T t) – boolean isX() et void setX(boolean b) • Peuvent ou non être déclarés dans l'interface • Ne doivent pas exécuter de logique métier • Si une exception est levée dans getX ou setX , la transaction rollback. private transient String _pwdDecrypté; • Attributs non persistant: Thibault Cuvillier Creative Commons 2.0 @Transient public String getPwdDecrypté() {…} javax.persistence / Introduction 29
  30. 30. @Basic, @Temporal • Indique un mapping simple pour une propriété persistante – Par défaut, toutes les propriétés sont persistantes • @Basic – fetch = EAGER ou LAZY – optional = @Basic true ou false @Temporal(TemporalType.DATE} • @Temporal public Date getDateNaissance() { – value = TIMESTAMP , return _ddn; DATE, TIME } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 30
  31. 31. Mapping 1 propriété / 1 colonne 1/3 • Utilisez l'annotation @Column – name: Nom de la colonne - Nom de la propriété – insertable : utilisée dans INSERT? - true – updatable : utilisée dans UPDATE? - true • Pour pouvoir générer le schéma: – nullable : peut être NULL? - true – unique : Valeur est unique dans la table - false – columnDefinition - Définition SQL de la colonne – length : longueur de la column - 255 – precision , scale pour les colonnes numérique - 0 Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 31
  32. 32. Mapping 1 propriété / 1 colonne 1/3 • Colonne "NOM" VARCHAR(255) private String _nom; public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } private String _nom; • Colonne "NAME" VARCHAR(32) @Column(name="NAME", length=32) public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } private String _nom; • Colonne "NAME" VARCHAR(32) NOT NULL Thibault Cuvillier Creative Commons 2.0 @Column(name="NAME", length=32, nullable=false) public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } javax.persistence / Introduction 32
  33. 33. Mapping 1 propriété / 1 colonne 3/3 • Colonne "DESC" CLOB private String _desc; @Column(columnDescription="CLOB") public String getDesc() { return _desc; } public void setDesc(String desc) { _desc = desc; } private Time _time; • Colonne "TIME" TIMESTAMP @Column(columnDescription="TIMESTAMP") public Time getTime() { return _time; } public void setTime(Time time) { _time = time; } • Colonne "SOLDE"private double _solde; Non modifiable @Column(precision=12, updatable="false") public double getSolde() { return _solde; } public void setSolde(double solde) { _solde = solde; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 33
  34. 34. Mapping O/R > Identité simple • Mapping O/R Mapping simple Identité simple Callback Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 34
  35. 35. Identité • L'identité d'une Entité = Clef Primaire • Identité métier: – Identité simple = Une seule valeur – Identité composite = Plusieurs valeurs • Identité technique: une colonne neutre – Entier long – Séquence Oracle, Colonne automatique MySQL… ! L'identité d'une entité doit être invariable . Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 35
  36. 36. Recommandations • N'utilisez que des Identificateurs neutres – Long ou long – Initialisation: séquence, table de compteurs, colonnes à incrémentation automatique… • Ajoutez si nécessaire des colonnes pour améliorer la performance des requêtes <<Table>> Soctété id nom prénom téléphone sociétéId id nom Thibault Cuvillier Creative Commons 2.0 <<Table>> Facture <<Table>> Client id clientId sociétéId montantHT montantTTC tva javax.persistence / Introduction 36
  37. 37. Identité simple 1/4 • La propriété contenant l'identité: @Id • Pour une identité technique générée: • @GeneratedValue – strategy NONE: pas de génération - Valeur par défaut TABLE: utilisation d'une table pour gérer les ID SEQUENCE: utilisation de séquences (Oracle par ex.) IDENTITY: génération de la valeur par la base AUTO: génération par le fournisseur de persistance – String generator (Si generate != NONE) Nom du générateur Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 37
  38. 38. Identité simple 2/4 • La valeur de l'ID est contrôlée par l'application @Id public long getId() { return _id; } @Id • La valeur de l'ID est fixée lors d'un INSERT par une séquence. @GeneratedValue(strategy=GenerationType.SEQUENC E, generator="CLIENT_ID_SEQ") @SequenceGenerator( name="CLIENT_ID_SEQ", sequenceName="CLIENT_ID", initialValue=0, allocationSize=50) public long getId() { return _id; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 38
  39. 39. Identité simple 3/4 • Les ID sont générés à partir de la table IDGEN possédant une colonne ID_KEY (PK), ID_VAL. • La valeur de l'ID suivant utilise la clef "CLIENT_ID". @Id @GeneratedValue( strategy=GenerationType.TABLE, generator="CLIENT_ID_TBL") @TableGenerator( name="CLIENT_ID_TBL", table="IDGEN", pkColumnName="ID_KEY", valueColumnName="ID_VAL", pkColumnValue="CLIENT_ID", initialValue=1, allocationSize=25) public long getId() { return _id; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 39
  40. 40. Identité simple 4/4 • La valeur de l'ID est générée par la base, par une colonne à incrémentation automatique • Colonne Automatic MySQL, Identity HsQL @Id @GeneratedValue(strategy=GenerationType.IDENTITY) public long getId() { return _id; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 40
  41. 41. Mapping O/R > Callbacks • Mapping O/R Mapping simple Identité simple Callback Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 41
  42. 42. Callbacks • Méthodes déclenchées pour notifier les changements d'états d'une entité @Entity public class Login { private String password; private String cryptedPassword; @PrePersist @PreUpdate public void preUpdate() { cryptedPassword = crypt(password); } } Thibault Cuvillier Creative Commons 2.0 @PostLoad public void postLoad() { password = decrypt(cryptedPassword); } … javax.persistence / Introduction 42
  43. 43. Callbacks des entités • @PrePersist et @PostPersist – Appelé avant et après EntityManager.persist() • @PreRemove et @PostRemove – Appelé avant et après EntityManager.remove() • @PreUpdate et @PostUpdate – Appelé avant et après une maj dans la base • @PostLoad – Appelé après le chargement de l'entité Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 43
  44. 44. Listener d'entité • Vous pouvez mettre le code des callbacks dans un listener avec @EntityListener. Personne.java @Entity @EntityListener(com.btc.LogListener) public class Personne { …} ! Les listeners sont hérités ! LogListener.java public class LogListener { L'entité est passée en @PrePersist ! paramètre public void prePersist(Object o) { System.out.println("PrePersit(o=" + o+")"); } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 44
  45. 45. Travaux pratiques • Ouvrez le projet JP-Lab01-Mapping-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 45
  46. 46. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence EntityManager JP 1.1 - Template 1.0
  47. 47. EntityManager Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 47
  48. 48. EntityManager • Permet de changer l'état persistant des entités – Création, destruction, modification • Associé à un contexte de persistance • Permet d'exécuter des requêtes – EJBQL: select c from client c where c.nom=:nom – Permet de fermer le contexte de persistance (J2SE) – Permet de contrôler les transactions (J2SE ou pas JTA) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 48
  49. 49. Création d'un EntityManager avec J2SE Attention, différent pour • L'EntityManager est créé par une un serveur J2EE factory • La factory contient la description du mapping EntityManagerFactory factory = Persistence.createEntityManagerFactory( "em", new Properties()); EntityManager em = factory.createEntityManager(); • Vous pouvez utiliser plusieurs contextes de persistance dans votre application – Une factory par contexte de persistence Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 49
  50. 50. persistence.xml • La factory est décrite dans le fichier Transactions: META-INF/persistence.xml •RESOURCE_LOCAL •JTA <?xml version="1.0" encoding="UTF-8"?> <persistence> <persistence-unit name="em" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="root"/> <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1/db"/> </properties> </persistence-unit> Attention avec un serveur J2EE, </persistence> utilisation de JNDI et de JTA Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 50
  51. 51. TRANSACTION et EXTENDED 1/2 • Le contexte de persistance maintient les données en cache. • Le cache peut avoir deux durées de vie: – TRANSACTION Les caches sont vidés à la fin de chaque transaction – EXTENDED Les caches sont vidés lorsque le contexte est fermé • Le cache peut être paramétré – Annotations et paramétrage XML non standard – Dépend de l'implémentation Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 51
  52. 52. TRANSACTION et EXTENDED 2/2 • Pour créer un EntityManager EXTENDED: EntityManagerFactory factory = Persistence.createEntityManagerFactory( "em", new Properties()); EntityManager em = _factory.createEntityManager( PersistenceContextType.EXTENDED ); … em.close(); • Il est préférable d'utiliser des caches transactionnels et de reposer ainsi sur l'isolation transactionnelle de la base Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 52
  53. 53. EntityManager.find • EntityManager.find(Class c, Object id) – Charge un objet en mémoire et le retourne • EntityManager.getReference(Class c, Object id) – Ne charge pas l'objet en mémoire, ne contient que l'ID. – L'état sera chargé lors du premier accès à une propriété persistante EntityManager em = … on verra plus loin …; Client client = em.getReference(Client.class, "Bill Gates"); em.remove(client); Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 53
  54. 54. Gérer les transactions EntityManager em = …; • Pas de transactions EntityTransaction tx = imbriquées em.getTransaction(); • S'il n'y a pas de transaction, tx.begin(); le contexte de persistance, try { … modifier les données … la méthode find: tx.commit(); – en commence une } catch(Exception e) { tx.rollback(); – la termine à la fin de la throw e; méthode } – retourne une entité détachée • Pour modifier les données dans la base, il suffit de modifier un objet géré Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 54
  55. 55. EntityManager.persist 1/2 • void persist(Object entity) Etat Action Transitoire Insertion dans la base (1) Géré Rien sur l'entité(1) Détaché IllegalArgumentException Détruit L'entité redevient managée (1) – (1) Cascade sur les entités référencées si cascade=PERSIST ou ALL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 55
  56. 56. EntityManager.persist 2/2 • Exemple: EntityManager em = …; EntityTransaction tx = em.getTransaction(); tx.begin(); Client client = new Client(); client.setPrénom("Harry"); client.setNom("Cover"); client.setTéléphone("0404040404"); em.persist(client); tx.commit(); System.out.println("Client id = " + client.getId()); Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 56
  57. 57. EntityManager.remove • void remove(Object entity) Etat Action Transitoire Rien sur l'entité, mais cascade (1) Géré Destruction de l'entité et cascade (1) Détaché IllegalArgumentException Détruit Rien – (1) Cascade sur les entités référencées si cascade=REMOVE ou ALL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 57
  58. 58. EntityManager.merge • <T> T merge(T entity) – Retourne une nouvel entité géré ! Attention, avec Hibernate, provoque une lecture de l'objet pour comparer son état. Etat Transitoire Géré Action Création de l'entité (1) Rien sur l'entité (1) Détaché Copie de l'état dans une entité gérée avec la même identité (1) IllegalArgumentException Détruit – (1) Cascade sur les entités référencées si cascade=MERGE ou ALL javax.persistence / Introduction Thibault Cuvillier Creative Commons 2.0 58
  59. 59. EntityManager.merge: exemple • La méthode fetch retourne l'objet persistant et le rend détache du contexte de persistance. • La méthode save met à jour l'objet dans le contexte de persistance. • fetch et save sont des méthodes transactionnelles public Client fetchClient(long idclient) { EntityManager em = …; return em.find(Client.class, idclient); } Ne pas utiliser getReference: pourquoi ? public void saveClient(Client client) { EntityManager em = …; em.merge(client); } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 59
  60. 60. Objets détachés • Un objet persistant devient détaché quand: – Le contexte de persistance se termine: • TRANSACTION: Fin de la transaction • EXTENDED: Fermeture explicite du contexte – Quand l'objet est sérialisé • Passage par valeur pour les interfaces Remote – Quand l'objet est cloné EJB Session EntityManager Navigateur Web GET EditClient.jsp Client c = fetchClient("Bill Gates") find SELECT POST EditClient.jsp saveClient(c) merge UPDATE Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction Base 60
  61. 61. Transactions optimistes 1/2 • Un objet peut être modifié entre sa lecture et son merge par une autre requête – La dernière écriture gagne • Transaction longue – Gestion pessimiste: vous devez gérer le verrouillage – Gestion optimiste: vous ajoutez une propriété Version • La version est incrémentée à chaque modification – Lors du merge, le contexte de persistance vérifie si le numéro de version a changé. – Exception dans ce cas, et rollback de la transaction Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 61
  62. 62. Transactions optimistes 2/2 • Il faut identifier la propriété contenant le numéro de version avec @Version – Peut être du type: int, Integer, long, Long, short, Short, Timestamp public Person { private long _version; @Version public long getVersion() { return _version; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 62
  63. 63. Mise à jour de la base de données • La base de donnée est mise à jour lors du commit ou avant l'exécution d'une query • Pour forcer la mise à jour: – EntityManager.flush() – Exécute le SQL • Vous pouvez recharger l'état d'un objet modifié à partir de la base: – EntityManager.refresh(Objet o) – Annule les modifications apportées Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 63
  64. 64. Travaux pratiques • Ouvrez le projet JP-Lab02-EntityManagerQuestion – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 64
  65. 65. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence EJBQL Niveau 1 JP 1.1 - Template 1.0
  66. 66. EJBQL Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 66
  67. 67. Queries EJBQL simples • EJBQL permet d'exécuter des requêtes – Pour lire des données – De faire des UPDATE et DELETE en masse • Utilise le nom des entités et des propriétés – Pas le nom des tables et colonnes – Attribut name de l'annotation @Entity – Abstract Schema Name select c from Client c where c.name="Alonso Bistrot" Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 67
  68. 68. La clause SELECT • SELECT c from Client c – Retourne tous les clients • SELECT c.name, c.email from Client c – Retourne le noms et l'email de tous les clients • SELECT COUNT(c) from Client c – Retourne le nombre de clients • SELECT AVG(c.age) from Client c – Retourne l'age moyen des clients – Autres fonctions: SUM, MIN, MAX Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 68
  69. 69. DISTINCT, ORDER BY, NEW • Select DISTINCT c.name from Client c – Retourne une liste de nom unique • Select c from Client c order by c.name ASC – Retourne la liste des clients triés par ordre alpha. – Ascendant: ASC (par défaut), Descendant: DESC • Permet de retourner une liste d'objets Java quelconque – Pas forcément des entités select new com.btc.EmployeInfo(e.id, e.status, e.salaire) from Employe e Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 69
  70. 70. Opérateurs de la clause WHERE 1/2 • [NOT] BETWEEN – WHERE c.age BETWEEN 0 and 17 – Equivalent à: c.age >= 0 AND c.age <= 17 • [NOT] LIKE – select c from Client c where c.name LIKE 'B%' – select c from Client c where c.name LIKE 'B_ _ _' • [NOT] IN – select c from Commande c where c.status IN('E', 'A', 'B') • IS [NOT] NULL – select c from Client c where c.status IS NULL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 70
  71. 71. Fonctions EJBQL • CONCAT("a", "b") => "ab" • TRIM([BOTH, " ", ]" a ") => "a" – 1er argument: BOTH, LEADING, TRAILING • • • • • • • • • LOWER("A") => "a" UPPER("a") => "A" LOCATE("ababab", "b" [, 3]) => 4 LENGTH("abcd") => 4 SUBSTRING("abcde", 2, 3) => "bcd" ABS(-2) => 2 SQRT(4) => 2 MOD(101, 10) => 1 SIZE(c.commandes) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 71
  72. 72. Opérateurs de la clause WHERE 3 • EXISTS – Vrai si la sous-requête retourne au moins un objet SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ( SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = emp.spouse) • ALL, ANY (ou SOME) – ALL: Vrai si toutes les valeurs remplissent la condition – ANY: Vrai si une valeur au moins remplie la condition SELECT emp FROM Employee emp WHERE emp.salary > ALL ( SELECT m.salary FROM Manager m WHERE m.department = emp.department) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 72
  73. 73. GROUP BY • GROUP BY permet de regrouper les valeurs retournées par la requête • Requête sans clause GROUP BY: Entreprise SUN Montant 5500 IBM SUN 4500 7100 Entreprise Montant SUN 17100 IBM 17100 SUN 17100 Entreprise Montant IBM 4500 SUN 12600 select v.entreprise, SUM(v.montant) from Vente v • Requête avec la clause GROUP BY: select v.entreprise, SUM(v.montant) from Vente v group by c.entreprise Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 73
  74. 74. HAVING • Permet de tester des valeurs agrégées – Impossible dans une clause WHERE select v.entreprise, SUM(v.montant) from Vente v group by v.entreprise having sum(v.montant) > 10000 Thibault Cuvillier Creative Commons 2.0 Entreprise Montant SUN 12600 javax.persistence / Introduction 74
  75. 75. DELETE et UPDATE • Permet de déclencher des delete et update de masse dans un batch. • DELETE: • UPDATE: delete from Client c where c.status = 0 update Employe c set c.salary = 1500 where c.salary < 1500 • Le contexte de persistance n'est pas mis à jour • Utiliser: – Dans une transaction séparée – Au début d'une nouvelle transaction Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 75
  76. 76. Exécuter une requête simples • Les requêtes simples public List findClients(EntityManager em) { Query query = em.createQuery ("select c from Client c"); return query.getResultList (); } • Avec des paramètres public List findClientsParStatus(EntityManager em, int status) { Query query = em.createQuery("select c from Client c where c.status = :status"); query.setParameter("status", status); return query.getResultList(); } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 76
  77. 77. Requêtes nommées • Déclarer les requêtes dans une annotation @NamedQueries( @NamedQuery( name="getByName", query="select e from Entreprise where name=:name"), @NamedQuery(name="getAll", query="select e from Entreprise") ) public class EntrepriseMgr { public List<Entreprise> getEntreprises() { Query query = _em.createNamedQuery("getAll"); return query.getResultList(); } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 77
  78. 78. Utiliser le SQL natif • Vous pouvez utiliser des requêtes SQL public List getClients() { Query query = _em.createNativeQuery ("select * from client", Client.class); return query.getResultList(); } • Vous pouvez utiliser @NamedNativeQuery Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 78
  79. 79. Mapping d'un ResultSet • Vous pouvez mapper chaque colonne sur une ou plusieurs classes – Pas forcément des entités @SqlResultSetMapping( name="getClientsSummariesResults ", entities=@EntityResult(entityClass=com.valtech.ClientSummary, fields={ FieldResult(name="id" column="client_id"), FieldResult(name="name" column="client_name") }) ) public List getClientSummaries() { return _em.createNativeQuery( "select c.id as client_id, c.name as client_name from client c", " getClientsSummariesResults "). getResultList(); } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 79
  80. 80. Travaux pratiques • Ouvrez le projet JP-Lab03-EJBQL-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 80
  81. 81. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence Mapping O/R Niveau 2 JP 1.1 - Template 1.0
  82. 82. Mapping avancé Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 82
  83. 83. Mapping des relations Mapping avancé Mapping des relations Mapping de l'héritage Autres mappings Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 83
  84. 84. Relations entre Entités • Support des relations 1-1, 1-n, n-m • Les relations peuvent uni ou bidirectionnelles • Certaines opérations peuvent se propager au travers des relations – Cascade: remove, persist, merge … remove – Que sur les relations OneToOne ou OneToMany Commande remove Ligne1 Thibault Cuvillier Creative Commons 2.0 remove Ligne2 javax.persistence / Introduction remove Ligne3 84
  85. 85. Relation 1-1 Map sur la table PERSONNE Propriétaire de la relation @Entity public class Personne { private long _id; private Login _login; @OneToOne public Login getLogin() { return _login; } public void setLogin(Login login) { _login = login; } Map sur la colonne ID Map sur la table LOGIN @Entity public class Login { private Personne _personne; private String _login; private Stirng _password; @OneToOne(mappedBy="login") public Personne getPersonne() { return _personne; } public void setPersonne(Personne p) { _personne = p; } } PERSONNE contient une FK sur LOGIN colonne = <Propriété>_<column PK> = LOGIN_ID Thibault Cuvillier Creative Commons 2.0 Optionnel si la relation est unidirectionnelle } javax.persistence / Introduction 85
  86. 86. Annotation OneToOne • @OneToOne – (O) String mappedBy = "" Propriété propriétaire de la relation – (O) boolean optional = true Peut ou non être null – (O) targetEntity = type de la propriété Le type de l'entité référencée – (O) CascadeType [] cascade = {} Opérations à cascader au travers de la relation: ALL, PERSIST, REMOVE, REFRESH – (O) fetchType fetch = EAGER Accès aux entités en mode LAZY ou EAGER Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 86
  87. 87. Fetch des entités • EAGER: – Les objets liés sont chargés en une seule requête SQL 1 find(Personne.class, id) 2 getLogin() EntityManager Personne Login • LAZY: – Chargement de l'identité – Chargement de l'état lors du premier accès 1 find(Personne.class, id) 2 getLogin() Thibault Cuvillier Creative Commons 2.0 EntityManager Personne javax.persistence / Introduction Login 87
  88. 88. Relation 1-n Map sur la table LOGIN Propriétaire de la relation @Entity public class Login { private long _id; private Role _role; Map sur la colonne ID Map sur la table ROLE @Entity public class Role { private long _id; private List<Login> _logins; @ManyToOne public Role getRole() { return _role; } public void setRole(Role r) { _role = r; } Optionnel si la relation est unidirectionnelle @OneToMany(mappedBy="role") public List<Login> getLogins() { return _logins; } public void setLogins(List<logins> l) { _logins = l; } } } LOGIN contient une FK sur ROLE colonne = <Propriété>_<column PK> = ROLE_ID Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 88
  89. 89. Intégrité des relations • C'est au développeur d'assurer l'intégrité des relations – Positionner la relation inverse Login login = new Login(); Person person = new Person(); – Lors du chargement, le lien inverse est positionné login.setPerson(person); automatiquement person.setLogin(login); • Une relation est mise à jour dans la base à partir de son propriétaire Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 89
  90. 90. Annotations ManyToOne et OneToMany • ManyToOne: même attributs que OneToOne • OneToMany: même attributs que OneToOne – Sauf fetch qui vaut LAZY • Avec les collections génériques: @OneToMany(mappedBy="role") List<Personne> getPersonnes() {…} • Avec les collections non génériques: @OneToMany(targetEntity=Personne.class, mappedBy="role") List getPersonnes() {…} Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 90
  91. 91. Relation n-m Map sur la table ROLE Propriétaire de la relation @Entity public class Role { private long _id; private List<Authorization> _authorizations; @ManyToMany public List<Authorization> getAuthorizations() { return _authorizations; } public void setAuthorization(List<Authorization> a) { _authorizations = a; } } Map sur la table AUTHORIZATION Map sur la colonne ID @Entity public class Authorization { private long _id; private List<Role> _roles; Optionnel si la relation est unidirectionnelle @ManyToMany(mappedBy="authorizations") public List<Role> getRoles() { return _roles; } public void setRoles(List<Role> r) { _roles = r; } Table d'association: ROLE_AUTORIZATIONS PK: ROLE_ID PK: AUTHORIZATIONS_ID } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 91
  92. 92. Mapping d'une clé étrangère 1/2 Jointure composite Jointure simple @Entity public class Login { private long _id; private Role _role; @ManyToOne @JoinColumn( name="ROLE_FK") public Role getRole() { return _role; } } Thibault Cuvillier Creative Commons 2.0 @Entity public class Entreprise { private long _id; private Personne _pdg; @ManyToOne @JoinColumns( { @JoinColumn(name="PDG_FIRST_NAME_PK", referencedColumnName="FIRST_NAME"), @JoinColumn(name="PDG_LAST_NAME_PK") referencedColumnName="FIRST_NAME"), }) public Personne getPDG() { return _pdg; } } 92 javax.persistence / Introduction
  93. 93. Mapping d'une clé étrangère 2/2 • @JoinColumn – (O) String name Nom de la colonne contenant la clef étrangère. Par défaut: <Propriété du référant>_<PK du référé> – (O) String referencedColumnName Clef primaire dans la table du référencé – (O) boolean unique = false – (O) boolean nullable = true – (O) insertable = true – (O) updatable = true – (O) columnDefinition – (O) secondaryTable (on verra plus loin) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 93
  94. 94. Mapping d'une table d'association • @JoinTable permet de préciser le nom de la table d'association @ManyToOne @JoinTable( name="ENTREPRISE_PDG", joinColumns = @JoinColumn(name="PDG_FK", referencedColumnName="ID"), inverseJoinColumns = @JoinColumn(name="ENT_FK", referencedColumnName="ID") ) public Personne getPDG() { return _pdg; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 94
  95. 95. Mapper une HashMap • Permet de mapper la valeur des clefs d'une Map – @MapKey: name contient le nom de la propriété persistante qui formera la clef – Par défaut: la clef primaire @OneToMany @MapKey(name="id") public Map<PersonneID, Personne> getEmployés() { return _employés; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 95
  96. 96. Ordre des relations • Permet d'ordonner les objets liés en fonction d'un ou plusieurs propriétés. • @OrderBy – Par défaut: la PK ASC @Entity public class Role { @Id long _id; private List<Login> _logins; @OneToMany(mappedBy="role") @OrderBy("user ASC") public List<Login> getLogins() { return _logins; } public void setLogins(List<logins> l) { _logins = l; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 96
  97. 97. BLOB et CLOB • Permet de préciser le type d'une colonne contenant un Large OBject @Entity – Propriété String public class Role { CLOB: données texte private JPEGImage _image; – Autre type de donnée @Lob BLOB: données binaires • fetch: EAGER ou @Basic(fetch=FetchType.LAZY) public JPEGImage getPhoto() { LAZY return _image; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 97
  98. 98. Travaux pratiques • Ouvrez le projet JP-Lab04-Relation-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 98
  99. 99. Mapping de l'héritage Mapping avancé Mapping des relations Mapping de l'héritage Autres mappings Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 99
  100. 100. Héritage • Une entité peut hériter d'une autre entité – Héritage des propriétés – Héritage des relations – Requêtes EJBQL polymorphes • Une entité peut être abstraite – Jamais instanciée – Possède un mapping O/R – Peut faire la cible de requêtes polymorphes • Une entité peut hériter d'une classe Java qui n'est pas une entité Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 100
  101. 101. Une table par hiérarchie • Une colonne donne le type de l'objet: – Le discriminant • Requête polymorphe: – select v from Voiture v where v.couleur ='rouge' Voiture id couleur 0..n 1 Berline barresDeToit Attention, toutes les propriétés doivent être nullable. Personne Cabriolet toit=capote, hardtop VOITURE disc Thibault Cuvillier Creative Commons 2.0 propriétaire id couleur proprietaire javax.persistence / Introduction barresDeToit toit 101
  102. 102. Une table par hiérarchie: exemple @Entity @Inheritance( strategy=SINGLE_TABLE) @DiscriminatorColumn(discriminatorType=STRING ) public abstract class Voiture { @Id long _id; private Personne _propriétaire; STRING, CHAR, private String _couleur; INTEGER … } • Chaque sous classe doit utiliser une valeur différente du discriminateur @Entity @DiscriminatorValue("B") public class Berline extends Voiture { private boolean barresDeToit; @Entity @DiscriminatorValue("C") public class Cabriolet extends Voiture { public enum Toit {HARDTOP, CAPOTE}; private Toit _toit; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 102
  103. 103. Une table par classe concrète • Consomme peu de place disque • Requêtes polymorphes coûteuses Voiture id couleur propriétaire 0..n 1 Berline Personne Cabriolet barresDeToit toit=capote, hardtop Le support de ce mapping est optionnel CABRIOLET BERLINE id couleur proprietaire Thibault Cuvillier Creative Commons 2.0 barresDeToit id couleur javax.persistence / Introduction proprietaire toit 103
  104. 104. Une table par classe concrète: exemple @Entity @Inheritance(strategy=TABLE_PER_CLASS) public abstract class Voiture { @Id long _id; private Personne _propriétaire; private String _couleur; … } @Entity public class Berline extends Voiture { private boolean barresDeToit; @Entity public class Cabriolet extends Voiture { public enum Toit {HARDTOP, CAPOTE}; private Toit _toit; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 104
  105. 105. Une table par classe • Proche du modèle objet • Performance des requêtes Voiture id couleur propriétaire 0..n Personne 1 Berline Cabriolet barresDeToit toit=capote, hardtop VOITURE id couleur proprietaire BERLINE id Thibault Cuvillier Creative Commons 2.0 barresDeToit javax.persistence / Introduction CABRIOLET id toit 105
  106. 106. Une table par classe: exemple @Entity @Inheritance(strategy=JOINED ) public abstract class Voiture { @Id long _id; private Personne _propriétaire; private String _couleur; … } @Entity public class Berline extends Voiture { private boolean barresDeToit; } • Les sous classes contiennent une FK sur la classe de base • Peut être renommée avec @PrimaryKeyJoinColum n @Entity public class Cabriolet extends Voiture { public enum Toit {HARDTOP, CAPOTE}; private Toit _toit; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 106
  107. 107. Travaux pratiques • Ouvrez le projet JP-Lab05-Inheritance-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 107
  108. 108. Autres mappings Mapping avancé Mapping des relations Mapping de l'héritage Autres mappings Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 108
  109. 109. Les classes embedded • Classe Java contenant une partie de l'état de l'entité @Embeddable public class Adresse { – Toujours un lien 1:1 @Entity Personne public class Personne { private Adresse _adresse; Adresse Colonnes de la table PERSONNE private String _rue; private String _ville; … } @Embedded @AttributeOverrides( { @AttributeOverride(name="rue", column=@Column(name="street")), @AttributeOverride(name="ville", column=@Column(name="city")) }) public Adresse getAdresse() { return _adresse; } public void setAdresse(Adresse adresse) { _adresse = adresse; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 109
  110. 110. Super classe mappées • Factorise des mapping communs entre classes • Pas d'annotation pour contrôler l'héritage – La super-classe est intégrée @MappedSuperclass public class Personne { dans la définition de private String _prénom; private String _nom; la sous classe @Entity @AttributeOverride( name="NomDeFamille", column = @Column(name="NOM2FAMILLE")) public class Employe extends Personne { private String _matricule; public String getMatricule() {…} } Thibault Cuvillier Creative Commons 2.0 public String getPrenom() {…} @Column(name="NOM") public String getNomDeFamille() {…} } javax.persistence / Introduction 110
  111. 111. Identité composite 1/2 • L'identité d'une Entité peut être encapsulé dans une classe – Bonne pratique: pourquoi ? • Deux solutions: @Embeddable public class PersonneID { private String _nom; @Entity public class Personne { L'identificateur mapprivate Date _ddn; sur une propriété … private PersonneID _id; public int hashCode() {…} public boolean equals(Object o) {…} @EmbeddedId } public PersonneID getID() { return _id; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 111
  112. 112. Identité composite 2/2 • Chaque propriété de l'identificateur map sur une propriété de l'entité @Entity @IdClass(ClientID.class) public class Client { private String _nom; private String _prenom; public class ClientID implements Serializable { private String _nom; private String _prenom; public ClientID() {} public getNom() {…} … public long hashcode() { … } public boolean equals(Object o) { … } public String getNom() { return _nom; } … } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 112
  113. 113. Mapper une classe sur plusieurs tables @Entity @Table(name="PERSONNE") @SecondaryTable( name="PERSONNE_DETAILS", pkJoinColumn=@PrimaryKeyJoinColumn( name="PERSONNE_FK")) public class Personne { private long _id; private String _prénom; private String _nom; private String _couleurYeux; private String _couleurCheuveux; @Column( name="COULEUR_YEUX", table="PERSONNE_DETAILS) public String getCouleurYeux() {…} public String getCouleurCheuveux() {…} } Thibault Cuvillier Creative Commons 2.0 • L'entité est répartie sur plusieurs tables • Plus d'une table secondaire: – @SecondaryTables PERSONNE id PRENOM … PERSONNE_DETAILS PERSONNE_FK COULEUR_YEUX javax.persistence / Introduction … 113
  114. 114. Travaux pratiques • Ouvrez le projet JP-Lab06-Embedded-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 114
  115. 115. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence EJBQL Niveau 2 JP 1.1 - Template 1.0
  116. 116. EJBQL avancé Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 116
  117. 117. Opérateurs sur les relations • IN(<Relation ToMany>) – Jointure entre deux entités – select c from Commande c, IN(c.lignes) l WHERE l.produit = 'Imprimante' • IS [NOT] EMPTY – select c from Commande c where c.lignes IS EMPTY • [NOT] MEMBER OF – Tester si une entité est ou non membre d'une relation Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 117
  118. 118. Les jointures SQL • Un JOIN permet de combiner les lignes de plusieurs tables • Deux types de jointures EJBQL: – [INNER] JOIN – LEFT [OUTER] JOIN • Prenons un exemple: id 1 2 3 Client nom John Doeuf Alain Disoir Sophie Fonfec Thibault Cuvillier Creative Commons 2.0 id 10 11 12 13 Commande client nom 1 Imprimante 2 Souris 2 Ecran null Clé USB javax.persistence / Introduction 118
  119. 119. INNER Join • Ne retourne pas les valeurs nulles de l'entité jointe – Il n'y a pas Sophie Fonfec dans le résultat ! • select c.nom, p.nom from Client c INNER JOIN c.produits p c.nom p.nom John Doeuf Alain Disoir Alain Disoir Imprimante Souris Ecran • Equivalent: – select c.nom, p.nom from Client JOIN c.produits p – select c.nom, p.nom from Client IN(c.produits) p javax.persistence / Introduction Thibault Cuvillier Creative Commons 2.0 119
  120. 120. LEFT OUTER JOIN • Retourne aussi les valeurs null de l'entité jointe • select c.nom, p.nom from Client c LEFT OUTER JOIN c.produits p c.nom John Doeuf Alain Disoir Alain Disoir Sophie Fonfec p.nom Imprimante Souris Ecran null • Equivalent: – select c.nom,p.nom from Client c LEFT JOIN c.produits p Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 120
  121. 121. FETCH • select p from Produit p JOIN p.client c – Lit les clients et produits en trois requêtes select p from Produit p JOIN p.client c load com.btc.join.Client load com.btc.join.Client Produit Imprimante Souris Ecran • select p from Produit p JOIN FETCH p.client c – Lit les clients et produits en une seule requête select p from Produit p JOIN p.client c Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 121
  122. 122. Sous-requêtes EJBQL • Une requête peut contenir une sous-requête SELECT c FROM Customer c WHERE ( SELECT COUNT(o) FROM c.orders o ) > 10 SELECT goodCustomer FROM Customer goodCustomer WHERE goodCustomer.balance > ( SELECT avg(c.balance) FROM Customer c ) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 122
  123. 123. Travaux pratiques • Ouvrez le projet JP-Lab07-EJBQL2-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 123
  1. A particular slide catching your eye?

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

×