Академический Документы
Профессиональный Документы
Культура Документы
Ce cours se divise en 2 parties : n persistance des objets n bases de donnes avances Ce support est une introduction la premire partie
Richard Grin
Richard Grin
Objet-relationnel
page 2
Le dcor
Une application complexe multi-tiers Le cours sintresse linterface entre le tiers mtier et le tiers base de donnes Lnorme majorit des base de donnes sont relationnelles et de nombreuses applications modernes sont crites avec des langages objet Comment une application crite dans un langage objet peut effectuer la persistance de ses objets dans une base de donnes relationnelle
Richard Grin Objet-relationnel page 4
Richard Grin
Objet-relationnel
page 8
Richard Grin
Objet-relationnel
page 11
Richard Grin
Objet-relationnel
page 12
Les couches
Prsentation, interface homme-machine (IHM) Traitements relatifs au domaine de lapplication (traitements mtiers ) avec les rgles de gestion en vigueur Enregistrement, rcupration et gestion des donnes persistantes dans une base de donnes
Richard Grin
Objet-relationnel
page 15
La couche de persistance
Elle est compose de la base de donnes Le plus souvent on y ajoute une couche qui effectue la correspondance (mapping) entre les objets et la base de donnes (DAO, ORM) En effet, le passage du monde objet au monde relationnel (ou plus gnralement des objets mtier aux donnes enregistres) peut ncessiter des traitements complexes Souvent cette couche sert aussi de cache pour les objets rcuprs dans la BD et amliore donc les performances
Richard Grin Objet-relationnel page 17
Richard Grin
Objet-relationnel
page 18
JDBC (Java Data Base Connectivity) permet l'accs des bases de donnes avec le langage SQL, depuis un programme en Java Il est fourni par le paquetage java.sql LAPI JDBC est presque totalement indpendante des SGBDs (quelques mthodes ne peuvent tre utilises quavec certains SGBDs mais ne doivent tre utilises quen cas de ncessit imprieuse pour amliorer les performances)
R. Grin JDBC page 2
Contenu de java.sql
Ce paquetage contient un grand nombre d'interfaces et quelques classes Les interfaces constituent linterface de programmation JDBC ne fournit pas les classes qui implantent les interfaces
R. Grin
JDBC
page 4
Drivers
Pour travailler avec un SGBD il faut disposer de classes qui implantent les interfaces de JDBC Un ensemble de telles classes est dsign sous le nom de driver JDBC Les drivers dpendent du SGBD auquel ils permettent d'accder Tous les SGBD importants du march ont un (et mme plusieurs) driver JDBC, fourni par l'diteur du SGBD ou par des diteurs de logiciels indpendants
R. Grin JDBC page 5
Types de drivers
Type 1 : pont JDBC-ODBC Type 2 : driver qui fait appel des fonctions natives non Java (le plus souvent en langage C) de l'API du SGBD que l'on veut utiliser Type 3 : driver qui permet l'utilisation d'un serveur middleware Type 4 : driver crit entirement en Java, qui utilise le protocole rseau du SGBD
R. Grin
JDBC
page 6
Les mthodes du driver JDBC font appel des fonctions d'une API du SGBD crite dans un autre langage que Java
Driver
Protocole du SGBD
SGBD
R. Grin JDBC page 7 R. Grin JDBC
SGBD
page 8
Les mthodes du driver JDBC se connectent par socket au serveur middleware et lui envoient les requtes SQL ; le serveur middleware les traitent en se connectant au SGBD
Les mthodes du driver JDBC utilisent des sockets pour dialoguer avec le SGBD selon son protocole rseau
SGBD
Protocole du SGBD
SGBD
R. Grin JDBC page 9 R. Grin JDBC
page 10
SGBD
R. Grin JDBC page 11 R. Grin JDBC page 12
Serveur HTTP
SGBD
JDBC page 13 R. Grin JDBC page 14
R. Grin
Charger en mmoire la classe du (des) driver (driver de type 4 fourni par Oracle pour cet exemple) avant d'utiliser JDBC :
Class.forName( "oracle.jdbc.driver.OracleDriver");
R. Grin
JDBC
page 15
R. Grin
JDBC
page 16
interroger la base (executeQuery()) ou modifier la base (executeUpdate()) ou tout autre ordre SQL (execute())
Avertissement
Nous tudierons tout d'abord les classes et mthodes de base de JDBC Les nouvelles possibilits de JDBC 2 et 3, en particulier celles qui sont lies SQL3, seront abordes dans une autre partie Dans la suite du cours on utilise des raccourcis du type instance de Connection Comme Connection est une interface, il faut traduire par instance dune classe qui implmente Connection
R. Grin
JDBC
page 19
R. Grin
JDBC
page 20
Interfaces principales
Driver : renvoie une instance de Connection Connection : connexion une base Statement : ordre SQL PreparedStatement : ordre SQL paramtr CallableStatement : procdure stocke sur le SGBD ResultSet : lignes rcupres par un ordre SELECT ResultSetMetaData : description des lignes rcupres par un SELECT DatabaseMetaData : informations sur la base de donnes
R. Grin JDBC page 21
Classes principales
DriverManager : gre les drivers, lance les connexions aux bases Date : date SQL Time : heures, minutes, secondes SQL TimeStamp : date et heure, avec une prcision la microseconde Types : constantes pour dsigner les types SQL (pour les conversions avec les types Java)
R. Grin
JDBC
page 22
Exceptions
SQLException : erreurs SQL SQLWarning : avertissements SQL (classe fille de SQLException) ; le mcanisme de rcupration des avertissements est tudi plus loin DataTruncation : avertit quand une valeur est tronque lors d'un transfert entre Java et le SGBD (classe fille de SQLWarning)
Interface Driver
La mthode connect() de Driver prend en paramtre un URL et renvoie une instance de l'interface Connection Cette instance de Connection permettra de lancer des requtes vers le SGBD connect renvoie null si le driver ne convient pas pour se connecter la base dsigne par l'URL
Gestionnaire de drivers
La classe DriverManager gre les drivers (instances de Driver) disponibles pour les diffrents SGBD utiliss par le programme Java Pour qu'un driver soit utilisable, on doit charger sa classe en mmoire :
Class.forName("oracle.jdbc.driver.OracleDriver");
La classe cre alors une instance d'elle mme et enregistre cette instance auprs de la classe DriverManager
R. Grin JDBC page 26
Connexions et threads
Les connexions sont des ressources coteuses, et surtout longues obtenir On peut donc tre tent de les rutiliser dans plusieurs threads diffrents Mais, attention, les connexions ne peuvent tre partages par plusieurs threads la place, utiliser les pools de connexions fournis avec les sources de donnes (tudies dans une autre partie du cours)
R. Grin JDBC page 28
La classe DriverManager s'adresse tour de rle tous les drivers qui se sont enregistrs (mthode connect), jusqu' ce qu'un driver lui fournisse une connexion (ne renvoie pas null)
R. Grin JDBC page 27
Transactions
Par dfaut la connexion est en auto-commit : un commit est automatiquement lanc aprs chaque ordre SQL qui modifie la base Le plus souvent il faut enlever l'auto-commit : conn.setAutoCommit(false) Il faut alors explicitement valider ou annuler la transaction par n conn.commit() n conn.rollback()
R. Grin JDBC page 29 R. Grin
Niveau disolation
Le niveau disolation dune transaction peut tre modifi :
conn.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE);
JDBC
page 30
R. Grin
JDBC
Interface ResultSet
executeQuery() renvoie une instance de ResultSet ResultSet va permettre de parcourir toutes les lignes renvoyes par le select Au dbut, ResultSet est positionn avant la premire ligne et il faut donc commencer par le faire avancer la premire ligne en appelant la mthode next() Cette mthode permet de passer la ligne suivante ; elle renvoie true si cette ligne suivante existe et false sinon
R. Grin JDBC page 34
JDBC
page 33
Interface ResultSet
Quand ResultSet est positionn sur une ligne les mthodes getXXX permettent de rcuprer les valeurs des colonnes de la ligne : n getXXX(int numroColonne) n getXXX(String nomColonne) (nom simple dune
colonne, pas prfix par un nom de table ; dans le cas dune jointure utiliser un alias de colonne)
ResultSet - performances
Quand le rseau est lent et que lon veut rcuprer de nombreuses lignes, il est parfois possible damliorer sensiblement les performances en modifiant le nombre de lignes rcupres chaque fois par le ResultSet (il faut effectuer des tests pour chaque cas) Pour cela, on utilise la mthode setFetchSize de Statement Cest seulement une indication quon donne au driver ; il nest pas oblig den tenir compte
R. Grin JDBC page 36
XXX dsigne le type Java de la valeur que l'on va rcuprer, par exemple String, Int ou Double Par exemple, getInt renvoie un int
R. Grin JDBC page 35
Types JDBC/SQL
Tous les SGBD n'ont pas les mmes types SQL ; mme les types de base peuvent prsenter des diffrences importantes Pour cacher ces diffrences, JDBC dfinit ses propres types SQL dans la classe Types, sous forme de constantes nommes Ils sont utiliss par les programmeurs quand ils doivent prciser un type SQL (setNull, setObject, registerOutParameter) Le driver JDBC fait la traduction de ces types dans les types du SGBD
R. Grin JDBC page 37
Types SQL3
page 38
n n n
CHAR et VARCHAR : getString, LONGVARCHAR : getAsciiStream et getCharacterStream BINARY et VARBINARY : getBytes, LONGVARBINARY : getBinaryStream REAL : getFloat, DOUBLE et FLOAT : getDouble DECIMAL et NUMERIC : getBigDecimal DATE : getDate, TIME : getTime, TIMESTAMP : getTimestamp
JDBC page 40
R. Grin
R. Grin
JDBC
page 42
Valeur NULL
Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery( "SELECT nomE, comm FROM emp"); while (rset.next()) { nom = rset.getString(1); commission = rset.getDouble(2); if (rset.wasNull()) System.out.println(nom + ": pas de comm"); else System.out.println(nom + " a " + commission + " de commission"); }
R. Grin JDBC page 43
R. Grin
JDBC
page 44
Les "?" indiquent les emplacements des paramtres Cette requte pourra tre excutes avec plusieurs couples de valeurs : (2500, DUPOND), (3000, DURAND), etc.
R. Grin
JDBC
page 46
R. Grin
JDBC
page 48
R. Grin
JDBC
page 49
Procdures stockes
Les procdures stockes permettent non seulement de prcompiler des ordres SQL mais aussi de les regrouper Comme les accs rseau aux bases de donnes ralentissent les applications, les procdures stockes permettent souvent damliorer les performances Mais elles nuisent aussi souvent la portabilit des applications
R. Grin JDBC page 51
Exemple
CallableStatement cstmt = conn.prepareCall("{? = call augmenter(?,?)}");
R. Grin
JDBC
page 55
csmt.setInt(1, 10); csmt.setDouble(2, 2.5); csmt.executeQuery(); // ou execute double cout = csmt.getDouble(3); System.out.println("Cout total augmentation : " + cout);
R. Grin JDBC page 57
Schma de code
boolean retval = cstmt.execute(); do { if (retval == false) { // pas un ResultSet int count = cstmt.getUpdateCount(); if (count == -1) break; // cest fini ! else { // traite lordre SQL . . . } } else { // ResultSet ResultSet rs = cstmt.getResultSet(); . . . // traite le ResultSet } retval = cstmt.getMoreResults(); while (true);
R. Grin JDBC page 60
execute renvoie true si le 1er rsultat est un ResultSet getMoreResults renvoie true si le rsultat suivant est un ResultSet getUpdateCount() : renvoie le nombre de lignes modifies, ou -1 s'il n'y a plus de rsultat (ou si le rsultat est un ResultSet)
On peut excuter tous les ordres dans une boucle dont la condition de fin est
!getMoreResults() && getUpdateCount() == -1
R. Grin JDBC page 59
10
Il faut Crer un type pour la rfrence de curseur quon va renvoyer Crer la fonction qui renvoie la rfrence de curseur
R. Grin
JDBC
page 62
Crer la fonction
create or replace function listdept(num integer) return Types.curseur_type is empcursor Types.curseur_type; begin open empcurseur for select dept, nomE from emp where dept = num; return empcurseur; end;
R. Grin
JDBC
page 63
R. Grin
JDBC
page 64
11
dates : {d '2000-10-5'} appels de fonctions : {fn concat("Hot", "Java")} jointures externes : con.createStatement("SELECT * FROM" + " {oj EMP RIGHT OUTER JOIN DEPT" + " ON EMP.DEPT = DEPT.DEPT}"); caractre dchappement utilis par LIKE : WHERE Id LIKE '_%\\' {escape '\'}
JDBC page 68
R. Grin
ResultSetMetaData
ResultSet rs = stmt.executeQuery("SELECT * FROM emp"); ResultSetMetaData rsmd = rs.getMetaData(); int nbColonnes = rsmd.getColumnCount(); for (int i = 1; i <= nbColonnes; i++) { String typeColonne = rsmd.getColumnTypeName(i); String nomColonne = rsmd.getColumnName(i); System.out.println("Colonne " + i + " de nom " + nomColonne + " de type " + typeColonne); }
R. Grin JDBC page 70
R. Grin
JDBC
page 69
DatabaseMetaData
private DatabaseMetaData metaData; private java.awt.List listTables = new List(10); . . . metaData = conn.getMetaData(); String[] types = { "TABLE", "VIEW" }; ResultSet rs = metaData.getTables(null, null, "%", types); String nomTables; Joker pour while (rs.next()) { noms des nomTable = rs.getString(3); tables et vues listTables.add(nomTable); }
R. Grin JDBC page 71
R. Grin
JDBC
page 72
12
Richard Grin
Ce cours explique les problmes de base qui se posent quand on veut faire correspondre n les donnes contenues dans un modle objet n avec les donnes contenues dans une base de donnes relationnelle Le cours sur JPA (Java Persistence API) donnera un exemple concret doutil qui automatise en grande partie cette correspondance
R. Grin Mapping objet-relationnel page 2
Prsuppos
La base de donnes relationnelle manipule par une application objet peut dj exister ou non au moment de la conception de lapplication objet Le cours qui suit suppose plutt que la base nexiste pas, mais le plus souvent les adaptations une base existante ne sont pas trs complexes et sont pris en charge par les outils de mapping
Une association
Dpartement numro : int nom : String lieu : String ajouterEmploy(Employe) : void 1 +contient
Agrgation
+subordonn
Unidirectionnel 0..*
hierarchie
0..*
appartient
Employe matricule : int nom : String poste : String 0..1 dateEmbauche : date salaire : double +suprieur getSuperieur() setSuperieur(Employe) getMatricule()
0..* +participe
0..*
Hritage
Directeur Administratif
R. Grin
Mapping objet-relationnel
page 3
R. Grin
Mapping objet-relationnel
page 4
2 paradigmes
Les paradigmes objet et relationnel sont bien distincts Le modle objet est plus riche (hritage, associations en particulier) Pas toujours simple de faire correspondre des objets et des donnes de tables relationnelles
R. Grin
Mapping objet-relationnel
page 5
R. Grin
Mapping objet-relationnel
page 6
Problme de base
Les objets persistants doivent tre enregistrs dans la base de donnes relationnelle Un objet a une structure complexe qui peut tre reprsente par un graphe Le plus souvent ce graphe est un arbre dont la racine correspond lobjet et les fils correspondent aux valeurs des variables dinstance qui sont persistantes Il faut aplatir ce graphe pour le ranger dans la base de donnes relationnelle
R. Grin Mapping objet-relationnel page 7
Plan
1. 2. 3. 4. 5. 6.
Exemple simple de traduction dune classe en une table Identification Traduction des associations Traduction de lhritage Navigation entre les objets Objet dpendant
R. Grin
Mapping objet-relationnel
page 8
Traduction dune classe en une table Exemple simple de traduction dune classe en une table
Dans les cas les plus simples une classe est traduite en une table Chaque objet est conserv dans une ligne de la table Exemple : la classe Dpartement est traduite par la table DPARTEMENT(numro, nom, lieu)
R. Grin
Mapping objet-relationnel
page 9
R. Grin
Mapping objet-relationnel
page 10
En SQL
create table departement ( numero smallint constraint pk_dept primary key, nom varchar(15), lieu varchar(15))
Identification
R. Grin
Mapping objet-relationnel
page 11
R. Grin
Mapping objet-relationnel
page 12
R. Grin
Mapping objet-relationnel
page 13
R. Grin
Mapping objet-relationnel
page 14
R. Grin
Mapping objet-relationnel
page 15
R. Grin
Mapping objet-relationnel
page 16
Exemple de duplication
Un objet p1 de la classe Produit de code s003 est cr en mmoire loccasion dune navigation partir dune ligne de facture On peut retrouver le mme produit en navigant depuis une autre facture, ou en cherchant tous les produits qui vrifient un certain critre Une erreur serait de crer en mmoire centrale un autre objet p2 indpendant du premier objet p1 dj cr
R. Grin Mapping objet-relationnel page 18
R. Grin
Mapping objet-relationnel
page 17
Objets insrs
Le modle objet peut avoir une granularit plus fine que le modle relationnel Les instances de certaines classes peuvent tre sauvegardes dans la mme table quune autre classe Ces instances sont appeles des objets insrs (embedded) et ne ncessitent pas didentificateur cl primaire
R. Grin
Mapping objet-relationnel
page 20
Exemple
Une classe Adresse na pas de correspondance sous forme dune table spare dans le modle relationnel Les attributs de la classe Adresse sont insres dans la table qui reprsente la classe Client Les objets de la classe Adresse nont pas didentification lie la base de donnes
R. Grin
Mapping objet-relationnel
page 21
R. Grin
Mapping objet-relationnel
page 22
R. Grin
Mapping objet-relationnel
page 24
Exemples de tables
create table DEPT ( . . .) create table EMPLOYE ( . . . num_dept integer references DEPT)
R. Grin
Mapping objet-relationnel
page 25
R. Grin
Mapping objet-relationnel
page 26
R. Grin
Mapping objet-relationnel
page 28
R. Grin
Mapping objet-relationnel
page 29
La cl peut, par exemple, reprsenter le matricule dun employ La variante avec map permet un accs rapide un des employs participant un projet La classe Projet reste identique la premire variante
R. Grin Mapping objet-relationnel page 32
R. Grin
Mapping objet-relationnel
page 31
R. Grin
Mapping objet-relationnel
page 34
En SQL :
create table participation ( matr integer references emp, codeP varchar(2) references projet, primary key(matr, codeP))
En objet
class Participation { private Employ employ; private Projet projet; private String fonction; . . . }
En relationnel
PARTICIPATION(matr, codeP, fonctionP)
En SQL :
create table participation ( matr integer references emp, codeP varchar(2) references projet, fonctionP varchar(15), primary key(matr, dept))
R. Grin
Mapping objet-relationnel
page 37
R. Grin
Mapping objet-relationnel
page 38
Association binaire dont une multiplicit maximum est 1 (N:1 ou 1:1) - Relationnel
On peut traduire les associations N:1 ou 1:1 en ajoutant une nouvelle relation, comme pour une association M:N Mais le plus simple est dajouter la cl de lautre classe dans la relation qui traduit la classe place du ct oppos la multiplicit 1 La 1re solution est plus souple mais plus coteuse (jointures)
R. Grin Mapping objet-relationnel page 39
En SQL :
create table emp ( matr integer primary key, dept smallint references dept)
R. Grin
Mapping objet-relationnel
page 40
R. Grin
Mapping objet-relationnel
page 43
R. Grin
Mapping objet-relationnel
page 44
Autre reprsentation
class Vol { private Collection<Reservation> rsas; . . . } class Reservation { private Passager passager; private int sige; . . . }
R. Grin
Mapping objet-relationnel
En SQL :
create table reservation( nvol varchar(10) references vol, nsiege integer, codePassager varchar(10) references passager, primary key(nVol, nSiege, codePassager), ...)
R. Grin
Mapping objet-relationnel
page 47
Objet dpendant
Un objet dont le cycle de vie dpend du cycle de vie dun autre objet auquel il est associ, appel objet propritaire Aucun autre objet que le propritaire ne doit avoir de rfrence directe vers un objet dpendant En ce cas, la suppression de lobjet propritaire doit dclencher la suppression des objets qui en dpendent (dclenchement en cascade )
R. Grin Mapping objet-relationnel page 50
Exemple
Une ligne de facture ne peut exister quassocie une (en-tte de) facture Si on supprime une facture, toutes les lignes de la facture doivent tre supprimes Tous les outils de mapping, comme JPA, offrent la possibilit dautomatiser les suppressions en cascade dobjets dpendants
Traduction de lhritage
R. Grin
Mapping objet-relationnel
page 51
R. Grin
Mapping objet-relationnel
page 52
Exemple
Pour fixer les ides, et ;-) pour reprendre des dessins du trs bon livre de Martin Fowler cit dans la bibliographie, on travaillera sur lexemple suivant tir du monde anglophone : n des sportifs qui peuvent tre des footballeurs ou des joueurs de crickets n parmi les joueurs de crickets, on distingue les joueurs qui lancent la balle : les bowlers
Pour en savoir plus sur le cricket : http://www.eleves.ens.fr/home/mlnguyen/divers/crick et/rules.html
R. Grin Mapping objet-relationnel page 53
Classe abstraite
Exemple
Sportifs qui peuvent tre des footballeurs ou des joueurs de crickets n Parmi les joueurs de crickets, les joueurs qui lancent la balle : les bowlers
n
R. Grin
Mapping objet-relationnel
page 54
R. Grin
Mapping objet-relationnel
page 55
Polymorphisme
Association polymorphe : une classe contient une rfrence vers une classe mre abstraite Par exemple, une socit garde une rfrence vers un sportif (dun sport quelconque) quelle sponsorise Requte polymorphe : cas o on veut une information qui correspond une proprit qui appartient une classe mre Par exemple, on veut les noms de tous les joueurs
R. Grin Mapping objet-relationnel page 58
Avantages
Souvent la solution la plus simple mettre en place Cest dailleurs la solution la plus frquemment choisie Permet les requtes et associations polymorphes
10
Inconvnients
Oblige avoir de nombreuses colonnes qui contiennent la valeur NULL On ne peut dclarer ces colonnes NOT NULL , mme si cette contrainte est vraie pour une des sous-classes
Colonne optionnelle
R. Grin Mapping objet-relationnel page 61 R. Grin Mapping objet-relationnel page 62
Prservation de lidentit
Un objet peut avoir ses attributs rpartis sur plusieurs tables (celles qui correspondent aux classes dune mme hirarchie dhritage) Son identit est alors prserve en donnant la mme cl primaire aux lignes qui correspondent lobjet dans les diffrentes tables Les cls primaires des tables correspondant aux classes filles sont des cls trangres vers la cl primaire de la classe mre
R. Grin Mapping objet-relationnel page 63
Prservation de lidentit
Pour rcuprer les informations sur une instance dune classe fille, il suffit de faire une jointure sur ces cls primaires
R. Grin
Mapping objet-relationnel
page 64
Avantages
Simple : bijection entre les classes et les tables Permet les requtes et associations polymorphes
Inconvnient
Si la hirarchie dhritage est complexe ncessite de nombreuses jointures pour reconstituer les informations parpilles dans de nombreuses tables Do des instructions complexes, mais surtout de mauvaises performances La colonne type de la table Players permet de limiter un peu ce problme ; il est possible, par exemple, de retrouver les noms des footballers sans faire de jointure
page 65 R. Grin Mapping objet-relationnel page 66
R. Grin
Mapping objet-relationnel
11
Remarque
Si une classe concrte se retrouve au milieu de larbre dhritage avec des classes filles (comme ici la classe Cricketer), il faudra que les classes filles concrtes aient la mme cl primaire que la classe mre concrte dans les tables correspondantes
R. Grin
Mapping objet-relationnel
page 67
R. Grin
Mapping objet-relationnel
page 68
Avantages
Cest la mthode la plus naturelle : une table par type dentit Pas de jointures pour retrouver les informations
Inconvnients
Ne peut traduire simplement les associations polymorphes Par exemple, une classe qui rfrence un joueur dun sport quelconque (joueur de football ou de cricket) En effet, aucune table relationnelle ne correspond un joueur dun sport quelconque et on ne peut donc imposer une contrainte dintgrit rfrentielle (cl trangre)
R. Grin Mapping objet-relationnel page 70
R. Grin
Mapping objet-relationnel
page 69
Solution
Aucune solution vraiment satisfaisante Des solutions partielles : n ignorer la contrainte dintgrit rfrentielle n mettre plusieurs colonnes dans la table qui rfrence, une pour chaque table concrte rfrence (mais a sera difficile dimposer lunicit de la rfrence ; sur lexemple, a sera difficile dimposer davoir une seule rfrence vers un joueur)
R. Grin Mapping objet-relationnel page 71
Autre problme
Dans le mme ordre dide, il est difficile dinterroger la base pour effectuer une requte polymorphe Par exemple, avoir le nom de tous les joueurs
R. Grin
Mapping objet-relationnel
page 72
12
Solution
On devra lancer plusieurs selects (un pour chaque sous-classe concrte) et utiliser une union de ces selects Le select sera donc plus complexe et sans doute moins performant
R. Grin
Mapping objet-relationnel
page 73
R. Grin
Mapping objet-relationnel
page 74
Variantes
Dans une arborescence dhritage ces stratgies peuvent tre mlanges On peut, par exemple, crer plusieurs tables pour plusieurs branches de larborescence dhritage Mais le risque est de retomber sur les problmes de la stratgie 3 (une table par classe concrte) avec les requtes et les associations polymorphes
R. Grin Mapping objet-relationnel page 75
Hritage multiple
Dans les cas o lhritage est traduit par des tables spares, lidentifiant dans les classes descendantes est lensemble des identifiants des classes mres
R. Grin
Mapping objet-relationnel
page 76
R. Grin
Mapping objet-relationnel
13
Une situation
Recherche dans la base de donnes dune facture qui vrifie un certain critre Un objet de la classe Facture qui correspond cette facture est cr Est-ce que les objets LigneFacture associs cette facture doivent aussi tre crs ? Et si la rponse est positive, faut-il crer aussi les objets Produit correspondants chaque ligne de facture ? Et si la rponse est positive,
R. Grin Mapping objet-relationnel page 79
Le problme
Le risque est de crer un trs grand nombre dobjets, peut-tre inutiles Par exemple, si on veut rcuprer cette facture pour connatre seulement la date de facturation, on voit que tous ces objets associs sont totalement inutiles Do de mauvaises performances, sans raisons valables
R. Grin
Mapping objet-relationnel
page 80
Rcupration paresseuse
La solution est le lazy loading , mot mot rcupration paresseuse , que lon peut traduire par rcupration la demande ou rcupration retarde
Rcupration paresseuse
Quand un objet est cr partir des donnes enregistres dans la BD, les objets associs ne sont pas immdiatement crs Lobjet cr contient juste linformation ncessaire pour retrouver ces objets associs (cl primaire) Ces objets ne seront crs que si cest vraiment indispensable
R. Grin
Mapping objet-relationnel
page 81
R. Grin
Mapping objet-relationnel
page 82
Exemple
Si on recherche la facture de numro 456, un objet f de la classe Facture est cr mais les objets correspondants aux lignes de la facture f ne sont pas crs Si le programme contient le code f.getLigne(i).getQuantite() lobjet LigneFacture correspondant la ime ligne de facture est cr et le message getQuantite() lui est envoy
R. Grin Mapping objet-relationnel page 83
R. Grin
Mapping objet-relationnel
page 84
14
Un exemple de N + 1 selects
On veut rcuprer la facture qui a le plus gros total, parmi 5000 factures Si la rcupration des lignes se fait la demande, les objets Facture sont dabord rcupres (1 select), puis, pour chacune des 5000 factures, les lignes de facture associes sont rcupres pour calculer le total (5000 selects) Do un total de 5001 selects, alors quon peut obtenir le rsultat avec un seul select !
R. Grin Mapping objet-relationnel page 85
R. Grin
Mapping objet-relationnel
page 86
R. Grin
Mapping objet-relationnel
page 88
R. Grin
Mapping objet-relationnel
page 89
15
R. Grin
Mapping objet-relationnel
page 91
16
Toutes les applications nont pas une complexit qui ncessite une architecture ntiers Ce cours dcrit les grands modles dapplications qui utilisent une base de donnes relationnelle
Richard Grin
Richard Grin
page 2
3 modles
Modle procdural Modle objet simple Modle objet avec utilisation dun outil de mapping videmment, ce dcoupage est trs schmatique Chacun de ces modles peut utiliser ou non des passerelles (DAO par exemple) pour isoler davantage le code qui gre la persistance
Richard Grin Types dapplication pour la persistance page 4
Richard Grin
page 3
Modle procdural
Richard Grin
Richard Grin
page 8
page 10
Richard Grin
page 11
Exemple
Une mthode qui recherche tous les employs dun dpartement Choix 1 :
List<Employe> rechercher(Dept dept)
de la classe Employe
Choix 3 : List<Employe> getEmployes() de la classe Departement
Richard Grin Types dapplication pour la persistance page 14
Dsavantages
Le dsavantage est que les classes mtier sont trop lies au support de persistance utilis Problme principal : tout refactoring entranant une modification de la hirarchie va obliger revoir le code de la persistance Mais ce refactoring est rare si le modle objet est simple Lutilisation du pattern DAO peut amliorer la situation, mais seulement partiellement
Richard Grin Types dapplication pour la persistance page 15
Richard Grin
page 16
Outils de mapping
La correspondance objet-relationnel est dcrite dans des fichiers des configuration ou par des annotations La persistance peut devenir presque transparente pour le dveloppeur qui crit le code Java Difficile dcrire soi-mme de tels outils car ils sont trs complexes
Richard Grin
page 17
Richard Grin
page 18
JPA
Spcification standard pour la persistance de objets Java (tudi la fin de ce cours) Implmentation de rfrence construite au dessus de Toplink Fait partie de la spcification EJB 3, framework pour les applications dentreprise
Hibernate
Avec Toplink, loutil de mapping le plus utilis dans le monde Java Utilise un gestionnaire de persistance, lintrospection et lenrichissement de code lexcution pour rcuprer les valeurs des proprits des objets et grer leur persistance En cours dadaptation au standard JPA
Richard Grin
page 19
Richard Grin
page 20
Autres possibilits
JDO (Java Data Objects) est une autre API qui offre des possibilits semblables JPA Utilise lenrichissement de code pendant la phase de compilation
Framework (cadre de
dveloppement)
Ensemble de classes et ressources prexistantes que le dveloppeur doit complter Utilisation dune librairie : lexcution est dirige par le code crit par le dveloppeur, qui fait appel aux classes de la librairie Utilisation dun framework : lexcution est dirige par le framework qui fait appel au code crit par le dveloppeur
Richard Grin Types dapplication pour la persistance page 22
Richard Grin
page 21
EJB
Le framework standard pour les applications Java dentreprise, EJB (Entreprise Java Beans), est fourni par J2EE, la version dentreprise de Java Il ncessite lutilisation dun serveur dapplication qui est un logiciel lourd rserver pour les grosses applications dentreprises
EJB
Les EJB sont des classes Java qui dcrivent le comportement des objets mtier Le dveloppeur crit le code li aux fonctionnalits des objets mtier, sans soccuper des services techniques (scurit, distribution sur plusieurs machines, transactions, persistance,) Le serveur dapplications utilise ce code pour y ajouter tous les services techniques indispensables au bon fonctionnement de lapplication
Richard Grin Types dapplication pour la persistance page 24
Richard Grin
page 23
EJB Entits
Il existe plusieurs types dEJB Les EJB entits correspondent aux objets mtier persistants Leur persistance peut tre entirement prise en charge par le container dEJB fourni par le serveur dapplication
Richard Grin
page 25
EJB version 3
EJB 3 revoit en grande partie les EJB entits Sappuie sur JPA pour la persistance (tudi dans la suite du cours) Les beans entits nont plus hriter de classes spciales et peuvent tre tests en dehors du serveur dapplications
Richard Grin
page 27
Richard Grin
page 28
Passerelle
Classe qui contient tout le code pour grer la persistance Chaque table a une classe passerelle qui lui correspond Le reste de lapplication fait appel aux passerelles pour grer la persistance
Passerelles
Richard Grin
page 29
Richard Grin
page 30
Utilisation
Isolent la persistance du reste de lapplication Facilitent les changements de SGBD et/ou permet dallger le code des classes mtier Peuvent tre utilises avec les 3 modles vus prcdemment
2 types de passerelle
Une instance de passerelle par table (le plus frquent) Une instance de passerelle par ligne de table Le pattern DAO (Data Access Object), trs utilis et tudi plus loin dans ce cours, correspond au type une passerelle par table
Richard Grin
page 31
Richard Grin
page 32
Exemple de passerelle
La classe EmployeDAO gre la persistance des instances de la classe Employe et correspond la table employe Elle contient la mthode ajouter(int matricule, String nom,) La mthode prend en paramtre les informations sur lemploy ajouter car il existe une seule instance de la classe EmployeDAO pour tous les employs
Richard Grin Types dapplication pour la persistance page 33 Richard Grin
Exemple de passerelle
Avec une instance de passerelle par ligne, on aurait une mthode ajouter() car la passerelle aurait toutes les informations sur lemploy auquel elle est lie
page 34
Bibliographie
Patterns of Entreprise Application Architecture de Martin Fowler Addison Wesley
Richard Grin
page 35
Ce cours prsente des modles de conception utiliss pour effectuer la persistance des objets
Richard Grin
R. Grin
Mapping objet-relationnel
page 2
Principe de base
Il est plus frquent de changer le modle de donnes des supports de persistance que de changer le modle mtier Pour faciliter ces changements il faut sparer le plus possible les entres-sorties des classes mtiers
DAO
Le code pour la persistance est isol dans des objets spcifiques, les DAO (Data Acess Objects)
R. Grin
Mapping objet-relationnel
page 3
R. Grin
Mapping objet-relationnel
page 4
R. Grin
Mapping objet-relationnel
page 5
R. Grin
Mapping objet-relationnel
page 6
DTO
Un DTO contient ltat dun ou de plusieurs objets mtier, mais pas leur comportement Synonyme : Transfert Object (TO)
R. Grin
Mapping objet-relationnel
page 7
R. Grin
Mapping objet-relationnel
page 8
Un fait important
Les appels de mthode distants sont beaucoup plus coteux que les appels locaux Le cot dpend peu de la quantit de donnes transfre chaque appel
Le problme rsoudre
Un client souhaite rcuprer des donnes en interrogeant des objets distants non facilement transportables sur le rseau Exemple : rcuprer les nom, prnom, salaire et lieu de travail dun employ Sil utilise les accesseurs des classes des objets (getNom, getPrenom, getSalaire, getLieu), plusieurs appels distants sont ncessaires
R. Grin Mapping objet-relationnel page 10
R. Grin
Mapping objet-relationnel
page 9
La solution
Le client demande un DTO la couche base de donnes , proche de la base de donnes qui contient toutes les valeurs dont il a besoin Cet objet est construit sur la couche base de donnes et pass en une seule fois au client
La solution
Un DTO peut aussi tre utilis, plus gnralement pour modifier un ou plusieurs objets distants (ou les donnes de la base de donnes) : n le DTO est cr ou modifi sur une couche de lapplication n il est pass une couche distante qui utilise ses donnes pour modifier un ou plusieurs objets distants (ou la base de donnes)
R. Grin Mapping objet-relationnel page 12
R. Grin
Mapping objet-relationnel
page 11
Le problme rsoudre
Le code pour la persistance varie beaucoup n avec le type de stockage (BD relationnelles, BD objet, fichiers simples, etc.) n avec les implmentations des fournisseurs de SGBD Si les ordres de persistance sont imbriqus avec le code mtier , il est difficile de changer de source de donnes
R. Grin
Mapping objet-relationnel
page 13
R. Grin
Mapping objet-relationnel
page 14
La solution
Encapsuler le code li la persistance des donnes dans des objets DAO dont linterface est indpendante du support de la persistance Le reste de lapplication utilise les DAOs pour grer la persistance, en utilisant des interfaces abstraites, indpendantes du support de persistance ; par exemple, Employe getEmploye(int matricule)
DAO
Quand lapplication a besoin deffectuer une opration lie la persistance dun objet, elle fait appel un objet DAO qui elle passe les informations ncessaires pour effectuer lopration Chaque classe dobjet mtier a son propre type de DAO (DAOEmploye, DAODepartement, ) Mais le mme objet DAO peut tre utilis pour tous les objets dune classe dobjet mtier
R. Grin Mapping objet-relationnel page 16
R. Grin
Mapping objet-relationnel
page 15
CRUD
Cet acronyme, souvent utilis dans le monde de la persistance, dsigne les 4 oprations de base de la persistance qui sont implmentes dans un DAO : create, retrieve, update et delete Les DAO peuvent aussi grer les connexions/dconnexions la source de donnes et les transactions
CRUD
Create pour crer une nouvelle entit dans la base Retrieve pour retrouver une ou plusieurs entits de la base Update pour modifier une des entits de la base Delete pour supprimer une entit de la base Plusieurs variantes pour les signatures de ces mthodes dans les DAOs
R. Grin Mapping objet-relationnel page 20
R. Grin
Mapping objet-relationnel
page 19
create
Prend en paramtre ltat de la nouvelle entit Cet tat peut tre donn n par une srie de paramtres des types des donnes : create(int id, String nom,) n par un DTO : create(DTOxxx dto) n par lobjet mtier que lon veut rendre persistant : create(Article article)
R. Grin
Mapping objet-relationnel
page 21
R. Grin
Mapping objet-relationnel
page 22
create
Le type retour peut tre n void (la variante la plus utilise) n boolean, pour indiquer si la cration a pu avoir lieu n lidentificateur de lentit ajoute (utile si lidentificateur est gnr automatiquement) n un objet mtier ou un DTO correspondant lentit ajoute La variante avec objet mtier a les mmes inconvnients (et avantages) que pour le passage de paramtre dun objet mtier
R. Grin Mapping objet-relationnel page 23
retrieve
3 types de finder, suivant quil retourne n un seul objet n une collection dobjets n une valeur calcule partir de plusieurs entits (agrgation)
R. Grin
Mapping objet-relationnel
page 24
R. Grin
Mapping objet-relationnel
page 25
update
Des variantes diverses pour les paramtres : n identificateur + valeurs (plusieurs paramtres pour les valeurs ou un seul DTO) n lobjet mtier dont on veut sauvegarder les modifications (ncessite un accs public aux valeurs qui seront modifies) Le type retour peut tre n void n boolean pour indiquer si la modification a pu avoir lieu
R. Grin Mapping objet-relationnel page 28
delete
Pour les paramtres : n identificateur de lentit supprimer dans la base n lobjet mtier (ou un DTO) correspondant lentit supprimer dans la base Pour le type retour : n void n boolean pour indiquer si la suppression a pu avoir lieu
R. Grin Mapping objet-relationnel page 29
DAO et exceptions
Les mthodes des DAO peuvent lancer des exceptions puisquelles effectuent des oprations dentres-sorties Les exceptions ne doivent pas tre lies un type de DAO particulier si on veut pouvoir changer facilement de type de DAO
R. Grin
Mapping objet-relationnel
page 30
DAO et exceptions
Pour cela, on cre une ou plusieurs classes dexception indpendantes du support de persistance, dsignons-les par DAException (ou DataAccessException ou DaoException) Les mthodes des DAO attrapent les exceptions particulires, par exemple les SQLException, et relancent des DAException (auxquels sont chanes les exceptions dorigine pour faciliter la mise au point)
R. Grin Mapping objet-relationnel page 31
2.
Chaque objet mtier a une rfrence son DAO et lutilise pour sa propre persistance. Le programme qui manipule les objets mtier ne connat pas les DAOs Le programme qui manipule les objets mtier utilise directement les DAOs. Les objets mtier nont pas de rfrence un DAO (stratgie sans doute la plus frquemment utilise)
R. Grin
Mapping objet-relationnel
page 32
Stratgie 1
Les programmes qui manipulent les objets mtier ne sont pas modifis par rapport un programme qui nutilise pas de DAO Seuls les objets mtier connaissent leur DAO Les objets mtier doivent avoir une rfrence vers le DAO quils utilisent Cette rfrence peut tre obtenue par une mthode static de la classe DAO (ce qui peut permettre de partager un DAO entre tous les objets mtier dune mme classe)
R. Grin Mapping objet-relationnel page 33
Exemple de code
class Stylo { private StyloDAO dao; ... on peut aussi public void sauvegardeToi() { construire un dao = getDAO(); TO pour le dao.insertOrUpdate(this); passer au DAO } private StyloDAO getDAO() { if (dao == null) Pour simplifier, on ne StyloDAO.getDAO(); tient pas compte des return dao; exceptions }
R. Grin Mapping objet-relationnel page 34
Stratgie 2
On rencontre le plus souvent la stratgie 2 On perd sans doute de la puret de la programmation objet
Exemple de code
// ou styloDAO = new StyloDAO() StyloDAO styloDAO = StyloDAO.getDAO(); int idStylo = styloDAO.create("Marker", "noir ", DTO ou objet 120,...); mtier . . . Stylo stylo = styloDAO.findById(idStylo); Nouvelles styloDAO.update(idStylo, ...); List<Stylo> l = styloDAO.findAll(); valeurs pour le stylo
R. Grin
Mapping objet-relationnel
page 35
R. Grin
Mapping objet-relationnel
page 36
Cette image (et les suivantes) sont extraites du Core J2EE Pattern Catalog de Sun
page 37 R. Grin Mapping objet-relationnel page 38
R. Grin
Mapping objet-relationnel
Diagramme de squences
DAO et connexions
Une connexion peut tre ouverte au dbut des mthodes du DAO, et ferme la fin des mthodes Cette stratgie peut coter cher si un pool de connexions nest pas utilis Le DAO peut aussi contenir des mthodes pour ouvrir et fermer une connexion ; en ce cas, une connexion peut tre utilise par plusieurs mthodes du DAO
Modification de plusieurs attributs persistants en utilisant un DTO : cration du DAO, puis rcupration des valeurs actuelles, R. Grin page 39 puis modification de ces Mapping objet-relationnel valeurs
R. Grin
Mapping objet-relationnel
page 40
DAO et transactions
Le plus souvent le DAO dmarre et termine lui-mme les transactions chaque mthode Dans les cas complexes, plusieurs DAOs associs plusieurs types dobjets mtier peuvent intervenir dans une transaction Dans ce cas, cest le client qui va grer les transactions Avec JDBC, a implique que les connexions ne sont pas ouvertes et fermes pour chaque mthode ; JTA na pas cette limitation
R. Grin Mapping objet-relationnel page 41
DAO et hritage
Le problme : une classe a des classes mres qui ont des proprits persistantes qui ne sont pas visibles de lextrieur (private, sans accesseurs visibles) Comment le DAO va pouvoir grer la persistance des instances de cette classe ?
DAO et hritage
La solution est de crer une hirarchie parallle de classes mappers dont les instances contiendront les mmes donnes que la hirarchie de la classe dont le DAO gre la persistance (voir le pattern Inheritance Mappers dans le livre de Martin Fowler donn dans la bibliographie) Chacune des classes mappers se charge des donnes qui la concerne pour fournir au DAO les donnes ncessaires aux changes avec la base de donnes
R. Grin Mapping objet-relationnel page 44
R. Grin
Mapping objet-relationnel
page 43
R. Grin
Mapping objet-relationnel
Exemple
La classe FabriqueDaoStylo contient une mthode getDao() qui renvoie un DaoStyloOracle ou un DaoStyloDb2 selon lenvironnement
Fabrique abstraite
Le pattern fabrique abstraite permet de changer facilement de source de donnes En une seule ligne de code tous les DAOs peuvent tre remplacs par des DAOs adapts la nouvelle source
R. Grin
Mapping objet-relationnel
page 47
R. Grin
Mapping objet-relationnel
page 48
Fabrique abstraite
Une fabrique abstraite est un type abstrait qui permet de cacher les types rels dun ensemble de fabriques concrtes Chaque fabrique concrte fournit tous les DAOs (DAOStylo, DAORamette,) associs une certaine source de donnes Dans la ligne de code, on rcupre la bonne fabrique de DAOs, associe la bonne source de donnes
R. Grin Mapping objet-relationnel page 49
Le type abstrait
La ligne de code pour DAOFactory daoFactory = changer de SGBD DAOFactory.getDAOFactory( DAOFactory.TypeDao.MYSQL); styloDAO = daoFactory.getStyloDAO(); // cre un nouveau stylo dans la base int styloNo = styloDAO.create(...); // Trouve un stylo StyloTO styloTO = styloDAO.find(...); // Modifie des valeurs du TO styloTO.setPrix(125); // Modifie le stylo dans la base styloDAO.update(styloTO);
R. Grin Mapping objet-relationnel page 50
...
Les DAOs crs
R. Grin Mapping objet-relationnel page 51 R. Grin Mapping objet-relationnel page 52
Une fabrique concrte cre tous les DAOs associs une source de donnes
R. Grin
Mapping objet-relationnel
page 53
R. Grin
Mapping objet-relationnel
page 54
La fabrique abstraite
public abstract class DAOFactory { public enum TypeDao {MYSQL, ORACLE}; public abstract StyloDAO getStyloDAO(); public abstract FactureDAO getFactureDAO(); ... public static DAOFactory getDAOFactory(TypeDao typeDao) { switch (typeFabrique) { case MYSQL: return new MysqlDAOFactory(); case ORACLE: return new OracleDAOFactory(); default: ... ; // erreur } } }
R. Grin Mapping objet-relationnel page 56
R. Grin
Mapping objet-relationnel
page 58
TO pour Stylo
import java.io.Serializable; public class StyloTO implements Serializable { private String reference; private String name; ... // Accesseurs et modificateurs public String getReference() {...} public void setReference(String ref) {...} ... }
R. Grin Mapping objet-relationnel page 60
10
Bibliographie
Patterns of Entreprise Application Architecture de Martin Fowler Addison Wesley Prsentation du pattern DAO et implmentation en Java, par Sun : http://java.sun.com/blueprints/corej2eepattern s/Patterns/DataAccessObject.html
R. Grin
Mapping objet-relationnel
page 61
11
Introduction
Richard Grin
R. Grin
Objet-relationnel
page 2
Modle objet-relationnel
Le modle objet-relationnel (OR) reprend le modle relationnel en ajoutant quelques notions qui comblent les plus grosses lacunes du modle relationnel La compatibilit est ascendante : les anciennes applications relationnelles fonctionnent dans le monde OR La norme SQL99 (SQL3) reprend beaucoup d'ides du modle OR
R. Grin Objet-relationnel page 3
R. Grin
Objet-relationnel
page 5
R. Grin
Objet-relationnel
page 7
R. Grin
Objet-relationnel
page 8
SQL99 (SQL3)
Cette partie du cours sappuie autant que possible sur les spcifications de SQL99 Le langage de programmation SQL99 ajoute SQL2 des variables et instructions de contrle pour en faire un langage procdural complet ; ce cours ne porte pas sur ces extensions Les exemples concrets sont donns dans le langage SQL de la version 10g dOracle ; les diffrences avec SQL99 seront signales
R. Grin Objet-relationnel page 12
R. Grin
Objet-relationnel
page 11
R. Grin
Objet-relationnel
page 13
R. Grin
Objet-relationnel
page 14
Types distincts
Ces types permettent de mieux diffrencier les domaines des colonnes ; ils sont forms partir des types de base :
CREATE TYPE codePays as char(2); CREATE TYPE matricule as integer;
Par exemple, pour diffrencier le domaine des colonnes matricule et numDept Ces types sutilisent exactement avec les mmes instructions que le type de base sousjacent
R. Grin Objet-relationnel page 15 R. Grin Objet-relationnel page 16
Types structurs
Correspondent aux classes des langages objets Ils peuvent contenir des constructeurs, attributs ( variables dinstances), fonctions et procdures ( mthodes) Les membres peuvent tre public, protected ou private Les fonctions et procdures peuvent tre crites en SQL ou en un autre langage
Un type ne peut contenir de contrainte dintgrit La commande create or replace type permet de redfinir un type sil existe dj
R. Grin Objet-relationnel page 18
R. Grin
Objet-relationnel
page 17
Hritage
Les types supportent lhritage multiple avec le mot-cl UNDER :
create type employe_type as object (matr integer, nom varchar(30), sal numeric(8,2)) not final; create type commercial_type under employe_type (comm numeric(8,2)) not final;
R. Grin
Objet-relationnel
page 21
R. Grin
Objet-relationnel
page 22
Type de ligne
SQL99 possde aussi la notion de type de ligne qui correspond aux structures du C : cest un ensemble non encapsul dattributs Le type peut tre nomm ou non
R. Grin
Objet-relationnel
page 23
R. Grin
Objet-relationnel
page 24
types
USER_OBJECT_TABLES pour les tables objet-
R. Grin
Objet-relationnel
page 25
R. Grin
Objet-relationnel
page 26
R. Grin
Objet-relationnel
page 27
R. Grin
Objet-relationnel
page 28
Hritage de tables
Une table peut hriter dune ou plusieurs tables Pas support par Oracle 10g
On peut crer une table partir de ce type et indiquer des contraintes dintgrit :
create table employe OF employe_type (primary key (matricule));
R. Grin Objet-relationnel page 29 R. Grin Objet-relationnel page 30
R. Grin
Objet-relationnel
page 31
Insertion de donnes
On ajoute des donnes comme avec une table normale : insert into commerciaux (matr, nom, sal, comm) values (234, 'TITI', 3200, 600);
relationnelles
R. Grin
Objet-relationnel
page 33
R. Grin
Objet-relationnel
page 34
Modifications
Utiliser la notation pointe comme en SQL92 :
update employe set employe.salaire = 12000 where employe.nom = 'Dupond';
SQL99 fournit aussi la notation .. pour dsigner un attribut dune colonne de type structur :
update employe set employe.adresse..numero = 12 where employe.nom = 'Dupond';
R. Grin
Objet-relationnel
page 35
R. Grin
Objet-relationnel
page 36
Rfrences
R. Grin
Objet-relationnel
page 37
R. Grin
Objet-relationnel
page 38
Rfrences
On peut indiquer dans la dfinition dun type quun attribut contient des rfrences (et non des valeurs) des donnes dun autre type ; la syntaxe est REF nom-du-type :
create type employe_type as object (matricule integer, nom varchar(30), . . . dept REF dept_type);
En SQL99 :
select nom, e.dept->lieu from employe e
R. Grin
Objet-relationnel
page 39
R. Grin
Objet-relationnel
page 40
insert into employe(matricule, nom, dept) select 1240, 'Dupond', REF(d) from dept d where dept.numDept = 10; rfrence vers le dept de numro 10
R. Grin Objet-relationnel page 41
Attention, cette instruction peut trs bien mettre la valeur NULL dans la colonne dept car le select renvoie NULL si le dpartement de numro 10 nexiste pas !
R. Grin Objet-relationnel page 42
R. Grin
Objet-relationnel
page 43
R. Grin
Objet-relationnel
page 44
Exemple de SCOPE
dept REF dept_type scope is dept_table
Rfrence perdue
SCOPE ne suffit pas pour imposer une contrainte stricte Ainsi la rfrence peut tre pendante (dangling) ou perdue , cest--dire ne pas correspondre une ligne existante, si la ligne rfrence au dpart a t ensuite supprime
indique que dept rfrencera une ligne de la table dept_table (et pas une ligne dune autre table cre partir du type dept_type)
R. Grin
Objet-relationnel
page 45
R. Grin
Objet-relationnel
page 46
References
Pour viter les rfrences perdues il faut remplacer la contrainte SCOPE par une contrainte REFERENCES (comme avec les tables relationnelles) :
dept REF dept_type references dept_table
Collections
R. Grin
Objet-relationnel
page 47
R. Grin
Objet-relationnel
page 48
Types de collections
Pour reprsenter une colonne multivalue, on peut utiliser les collections : n ensembles (au sens mathmatiques ; pas de doublons) n sacs (avec des doublons) n listes (ordonnes et indexes par un entier) Dautres types de collections peuvent tre ajoutes par les SGBD
Exemple de collection
create type employe_type (matricule integer, nom varchar(30), prenoms LIST(varchar(15)), enfants SET(personne), . . .);
R. Grin
Objet-relationnel
page 49
R. Grin
Objet-relationnel
page 50
R. Grin
Objet-relationnel
page 51
R. Grin
Objet-relationnel
page 52
Tables imbriques
Une table relationnelle (pas ncessairement OR) peut contenir une ou plusieurs tables imbriques Pas tudi dans ce cours ; se reporter au manuel Oracle pour plus de prcisions
Tableaux dimensionns
Un VARRAY est une collection ordonne et limite en nombre, dlments dun mme type On peut imbriquer plusieurs tableaux dimensionns en utilisant des pointeurs sur des tableaux
R. Grin
Objet-relationnel
page 53
R. Grin
Objet-relationnel
page 54
Exemple de VARRAY
create type telephones_type as VARRAY(3) OF varchar(10); insert into personne (nom, telephones) values('Dupond', telephones_type('0492077987', '0492074567'));
Rfrence
Programmer objet avec Oracle de Christian Soutou Vuibert
R. Grin
Objet-relationnel
page 55
R. Grin
Objet-relationnel
page 56
10
JDBC avanc
Universit de Nice - Sophia Antipolis
Version 1.8 14/10/06 Richard Grin
Transaction et exception Gnration des cls ResultSet avanc RowSet Regrouper les modifications BLOB et CLOB Pool de connexions, source de donnes Transaction distribue
R. Grin JDBC avanc page 2
Exception Rollback ?
Une exception ne provoque pas le rollback dune transaction Cest le code Java qui doit explicitement appeler la mthode rollback() sil le faut Une exception peut signaler un problme rcuprable ; en ce cas le programme peut choisir une alternative pour terminer correctement la transaction
Transactions et exceptions
R. Grin
JDBC avanc
page 3
R. Grin
JDBC avanc
page 4
Exemple
try { ... conn.commit(); } catch(SQLException e) { // La situation ne permet pas // de corriger le problme conn.rollback(); }
R. Grin
JDBC avanc
page 6
Exemple
try { ... conn.commit(); } catch(SQLException e) { // La situation est rcuprable. // Le code qui suit corrige le problme . . . conn.commit(); }
R. Grin JDBC avanc page 7
R. Grin
JDBC avanc
page 8
Gnration de cls
La gnration automatique de cls nest pas standardis Oracle utilise des squences (comme DB2 et PostgreSQL) Dautres SGBD utilisent dautres mthodes : n attribut AUTO_INCREMENT sur une colonne pour MySQL n attribut IDENTITY pour SQL Server n
R. Grin JDBC avanc page 9
getGeneratedKeys
Linterface Statement contient une mthode ResultSet getGeneratedKeys() qui renvoie toutes les cls gnres par lordre SQL, indpendamment de la manire dont elles ont t gnres, et sans accs supplmentaire la base de donnes Le ResultSet renvoy est vide si aucune cl na t gnre
R. Grin
JDBC avanc
page 11
R. Grin
JDBC avanc
page 12
Pour executeUpdate
Pour indiquer executeUpdate que lon souhaite rcuprer les cls gnres on doit indiquer dans un 2me paramtre n soit la valeur Statement.RETURN_GENERATED_KEYS n soit un tableau dentiers int[] indiquant les numros des colonnes du insert qui contiennent les cls gnrs que lon veut rcuprer
R. Grin JDBC avanc page 14
R. Grin
JDBC avanc
page 13
Exemple
Ajout dune nouvelle facture dans la base On a besoin de la cl gnre pour la facture pour la mettre en cl trangre dans les lignes de la facture (ne marche pas avec Oracle ; utiliser plutt seq.currval)
Exemple
Statement stmt = conn.createStatement(); // Ne pas oublier le 2me paramtre optionnel stmt.executeUpdate( "INSERT INTO facture VALUES(...)", Statement.RETURN_GENERATED_KEYS); ResultSet rsCles = stmt.getGeneratedKeys(); if ( rsCles.next() ) { int cle = rsCles.getInt(1); } // cle sera utilis pour insrer les // lignes de facture
R. Grin JDBC avanc page 16
R. Grin
JDBC avanc
page 15
Problme dimplmentation ?
Il semble que peu de drivers implmentent la mthode getGeneratedKeys Par exemple, le driver Oracle ne limplmente pas
R. Grin
JDBC avanc
page 17
ResultSet
JDBC avanc
page 20
Types de ResultSet
3 types de ResultSet : n TYPE_FORWARD_ONLY : ne peut pas tre parcouru que dans un sens n TYPE_SCROLL_INSENSITIVE : peut tre parcouru dans les 2 sens, mais ne reflte pas les modifications faites dans la base aprs la rcupration du ResultSet n TYPE_SCROLL_SENSITIVE : peut tre parcouru dans les 2 sens, et reflte les modifications faites dans la base aprs la rcupration du ResultSet
R. Grin JDBC avanc page 21
Types de ResultSet
Paralllement ces types, un ResulSet peut tre n CONCUR_READ_ONLY : on ne peut pas modifier les donnes en passant par le ResultSet n CONCUR_UPDATABLE : on peut modifier les donnes en passant par le ResultSet On peut donc avoir 6 types (3 x 2) de ResultSet En fait, tous les drivers ne les permettent pas avec de bonnes performances
R. Grin JDBC avanc page 22
R. Grin
JDBC avanc
page 23
R. Grin
JDBC avanc
page 24
R. Grin
JDBC avanc
page 25
R. Grin
JDBC avanc
page 26
R. Grin
JDBC avanc
page 27
R. Grin
JDBC avanc
page 28
ResultSet modifiable
Si le select et si la colonne du select le permettent, il est possible de modifier la valeur dune colonne dune ligne renvoye par le select et denregistrer cette modification dans la base de donnes Sinon, la mthode updateXXX ou la mthode updateRow lancera une exception
ResultSet modifiable
Le select dun ResultSet modifiable doit (cf. conditions sur les vues) n ne pas contenir de jointure ou de group by
n contenir la cl primaire de la table Les expressions des colonnes modifies doivent tre de simples noms de colonnes de tables Exemple de colonne non modifiable : une colonne qui contient une expression avec une fonction SQL
R. Grin JDBC avanc page 30
R. Grin
JDBC avanc
page 29
R. Grin
JDBC avanc
page 33
R. Grin
JDBC avanc
page 34
RowSet
R. Grin
JDBC avanc
page 35
R. Grin
JDBC avanc
page 36
Prsentation
ResulSet qui ont lavantage de se conformer au modle des Java Beans (srialisables, avec proprits, et observables par des couteurs) Reprsents dans lAPI par des interfaces, dont linterface racine javax.sql.RowSet hrite de ResultSet Le JDK 5 fournit des implmentations des diffrentes sous-interfaces de RowSet
Rowset dconnectable
Certains rowsets peuvent tre dconnects de la base aprs avoir rcupr des donnes dans la base On peut alors modifier leurs donnes en mode dconnect Le rowset peut ensuite se reconnecter et enregistrer les modifications dans la base
R. Grin
JDBC avanc
page 37
R. Grin
JDBC avanc
page 38
Sous-interfaces de RowSet
Interfaces du paquetage javax.sql.rowset : n JDBCRowSet : rowset qui reste connect n CachedRowSet : rowset dconnectable n WebRowSet : fille de CachedRowSet qui peut se sauvegarder au format XML n JoinRowSet et FilterRowSet : filles de WebRowSet qui reprsentent des rowsets sur lesquels on peut effectuer des jointures et des slections quand ils sont dconnects
R. Grin JDBC avanc page 39
JdbcRowSet
Cest essentiellement une enveloppe autour dun ResultSet, qui a les proprits dun Java bean Le rowset est modifiable (si le select le permet) et peut tre parcouru dans les 2 sens, mme sil enveloppe un resultSet qui ne le permettait pas Une implmentation est fournie avec la distribution Java : com.sun.rowset.JdbcRowSetImpl
R. Grin JDBC avanc page 40
JdbcRowSet
2 constructeurs : n avec un ResultSet en paramtre, pour envelopper un ResultSet existant n sans paramtre ; il faudra ensuite donner les informations pour la connexion la base et pour indiquer les donnes rcuprer
R. Grin
JDBC avanc
page 41
R. Grin
JDBC avanc
page 44
Exemple
rs.setCommand("select nome, salaire " + " from employe where dept = ?"); rs.setInt(1, 20); rs.execute();
Dplacement
Un rowset peut tre toujours tre parcouru dans les 2 sens La syntaxe est semblable celle de ResultSet
R. Grin
JDBC avanc
page 45
R. Grin
JDBC avanc
page 46
Modifications
Les donnes contenues dans le rowset peuvent tre modifies avec les mthodes habituelles de ResultSet Les mthode commit et rollback de JDBCRowSet valident ou invalident les modification de la transaction courante Elles ne doivent tre utilises que si la transaction nest pas en autoCommit ; voir mthodes {get|set}AutoCommit de JDBCRowSet (par dfaut la connexion est en autoCommit)
R. Grin JDBC avanc page 47
Exemple
rs.absolute(4); rs.updateString("nom", "Dupond"); rs.updateRow(); rs.beforeFirst(); rs.next(); rs.updateInt(3, 135); rs.updateRow(); rs.commit()
R. Grin
JDBC avanc
page 48
RowSet dconnectable
Interface CachedRowSet Il se connecte la base juste le temps de rcuprer des donnes Il peut tre dconnect de la base ; il est alors possible de lire, modifier, supprimer des donnes du rowset (mme syntaxe que ResultSet) en local Il peut ensuite se reconnecter pour rpercuter dans la base les modifications faites pendant la dconnexion (mthode acceptChanges())
R. Grin JDBC avanc page 49
Remplir un CachedRowSet
Un CachedRowSet peut tre rempli avec les donnes dun ResultSet par la mthode populate(ResultSet) Cependant le plus simple est souvent dinitialiser le CachedRowSet pour quil puisse se connecter la base (mthodes setUsername, setPassword, setUrl ou setDataSourceName), et indiquer la commande pour rcuprer les donnes (setCommand) On peut ensuite lancer cette commande par la mthode execute
R. Grin JDBC avanc page 50
Connexions la base
Les mthodes execute et acceptChanges peuvent recevoir en paramtre une connexion la base En ce cas, cette connexion est utilise pour lire ou crire les donnes dans la base de donnes Sinon, le rowset ouvre une connexion en interne en utilisant les proprits de connexion du rowset
R. Grin
JDBC avanc
page 52
R. Grin
JDBC avanc
page 54
Annulations de modifications
Les mthode undoInsert(), undoDelete() et undoUpdate() annulent la dernire modification de type insert, delete ou update effectue sur le rowset Il est ainsi possible dannuler plusieurs modifications qui ont t effectue depuis le dernier acceptChanges
Table modifie
Avec certains SGBD (Oracle en particulier) il peut tre ncessaire dindiquer la table sur laquelle les modifications seront faites, par la mthode setTableName(String) Avec dautres, le rowset peut avoir cette information par les mta donnes Des implmentations (Creator de Sun par exemple) utilisent cette mthode pour restreindre une seule table ce qui est insr dans la base lorsque le select du rowset concerne plusieurs tables (permet de modifier
des rowset qui ont un select avec jointure)
R. Grin JDBC avanc page 56
R. Grin
JDBC avanc
page 55
Conflits la reconnexion
Il peut videmment y avoir des conflits au moment de la reconnexion la base si les donnes initialement lues par le rowset ont t modifies pendant sa dconnexion Le traitement de ces conflits dpend de limplmentation du rowset Limplmentation de CachedRowSet fournie par dfaut utilise un blocage optimiste
R. Grin
JDBC avanc
page 57
R. Grin
JDBC avanc
page 60
10
R. Grin
JDBC avanc
page 62
R. Grin
JDBC avanc
page 63
Autres possibilits
release permet de vider un CachedRowSet : il ne contient plus aucune donnes (mais les informations sur la connexion ne sont pas touches)
R. Grin
JDBC avanc
page 66
11
Autres possibilits
CachedRowSet permet aussi dajouter des observateurs et de les avertir si on change de ligne, si une ligne est modifie ou si le rowset est rempli avec dautres donnes (add/removeRowSetListener, cursorMoved, rowChanged, rowSetChanged) Il est aussi possible de rcuprer les donnes dans la base page par page lorsquil y a une grande quantit de donnes rcuprer (setPageSize, nextPage, previousPage)
R. Grin JDBC avanc page 67 R. Grin
JDBC avanc
page 68
Performances
Dans les applications distribues il est important de rduire le nombre daccs distants aux bases de donnes pour amliorer les performances Les procdures stockes le permettent mais elles provoquent des problmes de portabilit On peut aussi regrouper plusieurs ordres SQL de type DML (insert, update, delete) pour les envoyer en une fois au SGBD Un driver JDBC peut ne pas implmenter cette fonctionnalit
R. Grin JDBC avanc page 69
Les mthodes
3 mthodes de linterface Statement (et donc aussi de ses sous-interfaces) permettent de manipuler les regroupements dordres SQL Elles peuvent lancer une SQLException void addBatch(String sql) : ajoute un ordre SQL la liste des ordres excuter int[] executeBatch() : excute les ordres SQL void clearBatch() : enlve toutes les ordres de la liste
R. Grin JDBC avanc page 70
Mthode executeBatch
Elle retourne un tableau dentiers qui indique le nombre de lignes modifies par chacun des ordres regroups ; la valeur peut tre ngative sil y a eu des problmes (voir javadoc pour plus de prcisions) Si une des commandes na pu tre excute correctement, une BatchUpdateException est renvoye ; les ordres SQL suivants sont excuts ou non suivant le driver (consulter la documentation du driver) ; on peut alors choisir de valider ou non la transaction
R. Grin JDBC avanc page 71
Exemple de regroupement
Statement stmt = conn.createStatement(); stmt.addBatch( "INSERT INTO DEPT " + "VALUES(70, 'Finances', 'Nancy')"); stmt.addBatch( "INSERT INTO DEPT " + "VALUES(80, 'Comptabilit', 'Nice')"); int[] nbLignes = stmt.executeBatch(); conn.commit();
R. Grin
JDBC avanc
page 72
12
JDBC avanc
page 74
Blob et Clob
La plupart des SGBD fournissait dj les types BLOB et CLOB mais n ces types n'taient pas normaliss n l'accs par JDBC n'tait pas normalis n les possibilits de manipulation de ces types taient restreintes (pas de recherche sur le contenu, par exemple) Il existe maintenant des types BLOB et CLOB et des interfaces Java Blob et Clob normaliss
R. Grin JDBC avanc page 76
Interface Clob
On peut lire le contenu d'une colonne de type Clob comme un flot de caractres ASCII ou Unicode par les mthodes (valable seulement jusqu' la fin de la transaction)
InputStream getAsciiStream() Reader getCharacterStream()
On peut aussi lire un Clob comme une String ; on peut rechercher la position d'une sous-chane de caractres dans un Clob, et extraire une partie du Clob :
long position(String sousCh, long debut) String getSubString(long pos, int longueur)
R. Grin JDBC avanc page 77
13
Avertissement
Les dernires parties de ce support ne sont que des survols rapides de possibilits avances offertes par JDBC et ses extensions Le but est de faire connatre lexistence de ces possibilits pour que le lecteur intress puisse approfondir leur tude par dautres sources
R. Grin
JDBC avanc
page 80
R. Grin
JDBC avanc
Pool de connexions
Les choix pour une politique de connexion sont facilits si on travaille avec un pool de connexions dj ouvertes et disponibles pour les clients Lorsque le client na plus besoin de la connexion, il appelle la mthode close() qui la restitue au pool (la connexion nest pas ferme)
R. Grin
JDBC avanc
page 83
R. Grin
JDBC avanc
page 84
14
Source de donnes
Depuis JDBC 3 (mais dj en extension de JDBC 2), on peut obtenir une connexion dune instance de javax.sql.DataSource (une interface) au lieu de lobtenir de la classe DriverManager Une DataSource reprsente une base de donnes (mais elle peut aussi reprsenter un simple fichier texte) Tout driver JDBC 2 doit fournir une implmentation de DataSource ; oracle.jdbc.pool.OracleDataSource pour Oracle
R. Grin JDBC avanc page 85
Mthode getConnection
La mthode principale de DataSource est getConnection(String utilisateur, String motDePasse) qui renvoie une Connection (et peut lancer une SQLException) Si le nom et le mot de passe de lutilisateur ont t entrs en dur dans la configuration de la source, on peut aussi utiliser la mthode getConnection()
R. Grin JDBC avanc page 86
Exemple dutilisation
OracleDataSource ds = new OracleDataSource(); ds.setURL("jdbc:oracle:thin:@sirocco.unic e.fr:1521:INFO"); ds.setUser("toto"); ds.setPassword("*****"); Connection conn = null; conn = ds.getConnection(); // Le reste est identique au code qui // nutilise pas de source de donnes . . .
R. Grin JDBC avanc page 88
Ce code ne peut fonctionner que dans un environnement dans lequel fonctionne un registre JNDI (serveur dapplications le plus souvent)
R. Grin JDBC avanc page 89
R. Grin
JDBC avanc
page 90
15
etc
R. Grin
JDBC avanc
page 92
Transactions JTA
R. Grin
JDBC avanc
16
JTA
Cette API fournit les classes pour travailler avec des transactions distribues sur plusieurs bases de donnes, ou mme des ressources qui ne sont pas des bases de donnes Elle est utilise par les serveurs dapplications
R. Grin
JDBC avanc
page 97
R. Grin
JDBC avanc
page 98
17
JDBC et relationnel-objet
Universit de Nice - Sophia Antipolis
Version 1.5 24/10/05 Richard Grin
JDBC supporte les types suivants de SQL3 qui sont des ouvertures vers le relationnelobjet : n ARRAY n types structurs dfinis par lutilisateur n rfrences vers des instances de types structurs
R. Grin
JDBC et relationnel-objet
page 2
Array
Le type de collection VARRAY dOracle permet d'avoir des colonnes multivalues Ils correspondent en Java la classe java.sql.Array
Rcuprer un Array
Un Array enregistr dans une base de donnes peut tre rcupr en Java sous la forme dune instance de la classe Array par les mthodes suivantes de ResultSet n getArray(String colonne nom) n getArray(int n) On rcupre ainsi une rfrence qui peut servir obtenir les valeurs de larray
R. Grin
JDBC et relationnel-objet
page 3
R. Grin
JDBC et relationnel-objet
page 4
Enregistrer un Array
void setArray(int i, Array x) de PreparedStatement permet denregistrer un Array On peut enregistrer un tableau Java sous forme de Array avec la mthode setObject
On peut aussi rcuprer un tableau Java entier par la mthode Object getArray() de Array
R. Grin JDBC et relationnel-objet page 5 R. Grin JDBC et relationnel-objet page 6
Enregistrer un tableau
String[] data; // remplit le tableau . . . PreparedStatement ps = conn.prepareStatement( "Update table1 " + "set tableau = ? where num = 5"); ps.setObject(1, data);
R. Grin
JDBC et relationnel-objet
Type utilisateur
SQL 3 a introduit 2 formes de nouveaux types crs par l'utilisateur : n type distinct , construit simplement partir d'un type de base n type structur , plus complexe, construit sur le modle d'une classe Java
R. Grin
JDBC et relationnel-objet
page 10
Type distinct
Ces types permettent de mieux diffrencier les domaines des colonnes, qu'avec les types de base :
create type codePays as char(2); create type matricule as integer;
Type structur
Ces types rapprochent les SGBD relationnels du monde objet Ils sont crs par la commande SQL 3 create type :
create type departement_type ( numDept integer, nomDept varchar(15), lieu varchar(20))
On peut ainsi, par exemple, diffrencier le domaine des colonnes matricule et numDept On utilise ces types exactement avec les mmes instructions que le type de base
R. Grin
JDBC et relationnel-objet
page 11
R. Grin
JDBC et relationnel-objet
page 12
R. Grin
JDBC et relationnel-objet
page 13
R. Grin
JDBC et relationnel-objet
page 14
Interface SQLData
public interface SQLData { void readSQL(SQLInput stream, String typeName) throws SQLException ; void writeSQL(SQLOutput stream) throws SQL Exception; String getSQLTypeName() throws SQLException; }
R. Grin
JDBC et relationnel-objet
page 15
R. Grin
JDBC et relationnel-objet
page 16
R. Grin
JDBC et relationnel-objet
page 17
R. Grin
JDBC et relationnel-objet
page 20
R. Grin
JDBC et relationnel-objet
page 21
R. Grin
JDBC et relationnel-objet
page 22
R. Grin
JDBC et relationnel-objet
page 23
Rfrences en SQL 3
Le processus de normalisation conduit clater les donnes en plusieurs tables Lorsque lon veut retrouver des informations, on doit alors souvent effectuer des jointures, par exemple pour savoir dans quelle ville les employs travaillent En SQL3 on peut le faire sans que cela ne ncessite de jointure En effet, SQL3 permet de manipuler les rfrences une information
R. Grin JDBC et relationnel-objet page 25
R. Grin
JDBC et relationnel-objet
page 26
R. Grin
JDBC et relationnel-objet
page 27
R. Grin
JDBC et relationnel-objet
page 28
R. Grin
JDBC et relationnel-objet
page 29
R. Grin
JDBC et relationnel-objet
page 30
R. Grin
JDBC
page 2
Autres API
Dautres API ont t construites au-dessus de JDBC pour corriger les problmes de JDBC : n SQLJ n JDO n outils de mapping n et bien dautres
R. Grin
JDBC
page 3
R. Grin
JDBC
page 4
SQLJ
SQLJ est un standard promu par un consortium dditeurs de SGBD (Oracle, IBM et Sun en particulier) compos de 3 parties La partie 0 de SQLJ fait partie de SQL3 Cette partie dfinit des extensions de SQL pour permettre dinsrer directement des ordres SQL au milieu dun programme Java Par exemple, une variable Java peut recevoir une valeur retourne par une requte SQL
page 5 R. Grin JDBC page 6
SQLJ
R. Grin
JDBC
Prcompilateur SQLJ
Un prcompilateur transforme les ordres SQL en instructions Java contenant des appels de mthodes JDBC Le rsultat est un programme source Java que lon peut compiler avec un compilateur Java ordinaire Ce prcompilateur contrle la validit des ordres SQL ; il en faut donc un par SGBD cible
R. Grin
JDBC
page 7
R. Grin
JDBC
page 8
Principe de SQLJ
Fichier de ressources Fichier source .java
Compilateur Java
Fichier .class
Ce procd est dj utilis pour de nombreux langages (C, Cobol, Ada,) pour insrer des instructions SQL
R. Grin
JDBC
page 9
JDO
R. Grin
JDBC
page 11
R. Grin
JDBC
page 12
JDO
JDO est un projet plus ambitieux que SQLJ puisquil souhaite rendre en grande partie transparente la persistance des objets Java Le code Java crit par les dveloppeurs ne soccupe pas de la persistance JDO ncessite une infrastructure complexe, la compilation, et durant lexcution, fournie par une implmentation JDO
Transparence de la persistance
Les classes qui pourront avoir des instances persistantes sont dites capables de persistantes Le principe de base de JDO est que le programmeur ncrit aucun code pour grer la persistance Le code source dune classe est exactement le mme, que la classe soit capable de persistance ou non
R. Grin JDBC page 14
R. Grin
JDBC
page 13
Portabilit
La persistance peut seffectuer sur un support logique quelconque : SGBD relationnel ou objet, ou mme fichiers ordinaires Il suffit davoir une implmentation JDO (qui joue le rle dun driver JDBC) adapte ce support La persistance ne tient compte que de la description logique des classes persistantes (mta-donnes), fournie par un fichier XML crit par le dveloppeur Il est ainsi trs facile de changer de support
R. Grin JDBC page 16
En fait la plupart des instances sont rendues persistantes automatiquement, par rfrence (by reachability) : si on rend persistant une instance de Employe, dont la classe possde un champ capable de persistance de type Adresse, son adresse devient automatiquement persistante
R. Grin JDBC page 15
Enrichissement JDO
Les classes capables de persistance sont indiques dans un fichier XML de configuration Elles doivent tre enrichies par un programme spcial, fourni par l'implmentation de JDO et adapt un SGBD cible Cet enrichissement ajoute les mthodes qui permettront limplmentation JDO de grer la persistance des instances pendant lexcution
R. Grin
JDBC
page 17
R. Grin
JDBC
page 18
Outils JDO
Les implmentations JDO fournissent des outils (pas obligatoires) pour n crer automatiquement des schmas de base de donnes compatibles avec les classes persistantes, n ou inversement, pour crer des classes compatibles avec des tables existantes
R. Grin
JDBC
page 19
Exemple (suite)
// Dmarrer une transaction Transaction t = pm.currentTransaction(); t.begin(); // Cre une nouvelle Adresse Adresse adresse = new Adresse("58 rue Victor Hugo", "Nice", "06100"); //... et la rend persistante pm.makePersistent(adresse); // adresse automatiquement enregistre dans la // base au commit ! t.commit(); // Fermeture du gestionnaire de persistance pm.close();
R. Grin JDBC page 22
R. Grin
JDBC
page 21
Outils de mapping
Ils automatisent la correspondance entre les donnes correspondant ltat des objets et les donnes enregistres dans les BDR Trs la mode en ce moment (hibernate en particulier) Ils sont tudis dans une autre partie du cours (mapping objet-relationnel)
R. Grin
JDBC
page 23
JPA
Prsentation de JPA Entits persistantes Gestionnaire de persistance Complments sur les entits : identit, associations, hritage Langage dinterrogation Modifications en volume Exceptions Configuration
R. Grin JPA page 2
Prsentation de JPA
R. Grin
JPA
page 3
R. Grin
JPA
page 4
EJB 3.0
Java EE 5 (Enterprise Edition) est une plateforme de dveloppement et un ensemble de spcifications pour le dveloppement dapplications dentreprises multi-tiers EJB 3.0 fait partie de Java EE 5 ; cest une spcification rcente (mai 2006) dun cadre (framework) pour lutilisation de composants mtier rutilisables par des serveurs dapplication Java Utilisation importante des annotations
R. Grin JPA page 5
JPA
JPA (Java persistence API) est la partie de la spcification EJB 3.0 qui concerne la persistance des composants Neffectue la persistance que dans une base de donnes relationnelle (JDO permet le choix dautres types de SGBD) Peut sappliquer sur toutes les applications Java, mme celles qui sexcutent en dehors dun serveur dapplication
R. Grin
JPA
page 6
JPA
JPA va sans doute devenir un standard pour la persistance des objets Java Pour plus de prcisions, lire la spcification ladresse http://jcp.org/aboutJava/communityprocess/pfd/js r220/index.html
Avertissement
JPA est le plus souvent utilis dans le contexte dun serveur dapplication Ce cours tudie lutilisation de JPA par une application autonome, en dehors de tout serveur dapplication Des informations sur lutilisation de JPA avec un serveur dapplications sont donnes la fin de ce support
R. Grin
JPA
page 7
R. Grin
JPA
page 8
Fournisseur de persistance
Comme pour JDBC, lutilisation de JPA ncessite un fournisseur de persistance qui implmente les classes et mthodes de lAPI GlassFish, est limplmentation de rfrence de la spcification EJB 3 GlassFish utilise TopLink essentials comme fournisseur de persistance pour JPA Dautres implmentations : TopLink, Hibernate Entity Manager, BEA Kodo
R. Grin JPA page 9
Entits
Les classes dont les instances peuvent tre persistantes sont appeles des entits dans la spcification de JPA Le dveloppeur indique quune classe est une entit en lui associant lannotation @Entity Ne pas oublier dimporter javax.Persistence.Entity dans les classes entits (idem pour toutes les annotations)
R. Grin JPA page 10
Vocabulaire
Dans la suite de ce cours et quand il ny aura pas ambigut, entit dsignera soit une classe entit, soit une instance de classe entit, suivant le contexte
R. Grin
JPA
page 11
R. Grin
JPA
page 12
R. Grin
JPA
page 13
R. Grin
JPA
page 14
R. Grin
JPA
page 15
R. Grin
JPA
page 16
Gestionnaire dentits
Classe javax.persistence.EntityManager Le gestionnaire dentits (GE) est linterlocuteur principal pour le dveloppeur Il fournit les mthodes pour grer les entits : les rendre persistantes, les supprimer de la base de donnes, retrouver leurs valeurs dans la base, etc.
Contexte de persistance
La mthode persist(objet) de la classe EntityManager rend persistant un objet Lobjet est alors gr par le GE : toute modification apporte lobjet sera enregistre dans la base de donnes par le GE Lensemble des entits gres par un GE sappelle un contexte de persistance
R. Grin
JPA
page 17
R. Grin
JPA
page 18
Exemple
EntityManagerFactory emf = Persistence. createEntityManagerFactory("employes"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Dept dept = new Dept("Direction", "Nice"); em.persist(dept); sera enregistr dans dept.setLieu("Paris"); la base de donnes tx.commit(); au moment du commit R. Grin JPA page 19
Exemple (suite)
String queryString = "SELECT e FROM Employe e " + " WHERE e.poste = :poste"; Query query = em.createQuery(queryString); query.setParameter("poste", "INGENIEUR"); List<Employe> liste = query.getResultList(); for (Employe e : liste) { System.out.println(e.getNom()); } em.close(); emf.close()
R. Grin JPA page 20
Caractristiques
Seules les entits peuvent tre n renvoyes par une requte (Query) n passes en paramtre dune mthode dun EntityManager ou dun Query n le but dune association n rfrences dans une requte JPQL Une classe entit peut utiliser dautres classes pour conserver des tats persistants (MappedSuperclass ou Embedded tudies plus loin)
page 21 R. Grin JPA page 22
Entits
R. Grin
JPA
R. Grin
JPA
page 24
2 types daccs
Le fournisseur de persistance accdera la valeur dune variable dinstance n soit en accdant directement la variable dinstance (par introspection) n soit en passant par ses accesseurs (getter ou setter) Le type daccs est dtermin par lemplacement des annotations (associes aux variables dinstance ou aux getter)
R. Grin JPA page 26
Vocabulaire JPA
Un champ dsigne une variable dinstance JPA parle de proprit lorsque laccs se fait en passant par les accesseurs (getter ou setter) Lorsque le type daccs est indiffrent, JPA parle dattribut
R. Grin
JPA
page 28
Attributs persistants
Par dfaut, tous les attributs dune entit sont persistants Lannotation @Basic indique quun attribut est persistant mais elle nest donc indispensable que si on veut prciser des informations sur cette persistance (par exemple, une rcupration retarde) Seuls les attributs dont la variable est transient ou qui sont annots par @Transient ne sont pas persistants
R. Grin JPA page 30
R. Grin
JPA
page 29
Jai oubli o jai pris cette image merci de me donner la rfrence si vous le savez
R. Grin JPA
Nom de table
Pour donner la table un autre nom que le non de la classe, il faut ajouter une annotation @Table Exemple :
@Entity @Table(name="AUTRENOM") public class Classe { ... }
R. Grin
JPA
page 35
R. Grin
JPA
page 36
Nom de colonne
Pour donner une colonne de la table un autre nom que le nom de lattribut correspondant, il faut ajouter une annotation @Column Cette annotation peut aussi comporter des attributs pour dfinir plus prcisment la colonne Exemple :
@Column(name="AUTRENOM", updatable=false, length=80) public String getTruc() { ... }
R. Grin JPA page 37
Classe Embeddable
Les entits persistantes ne sont pas les seules classes persistantes Il existe aussi des classes insres ou incorpores (embedded) dont les donnes nont pas didentit dans la BD mais sont insres dans une des tables associes une entit persistante Elles peuvent tre annotes comme les entits (avec @Column par exemple) Par exemple, une classe Adresse dont les valeurs sont insres dans la table Employe
R. Grin JPA page 38
Classe Embeddable
Comme les entits, ces classes doivent avoir un constructeur sans paramtre Les types permis pour leurs attributs sont les mmes que les types permis pour les attributs des entits
Exemple
@Embeddable public class Adresse { private int numero; private String rue; private String ville; . . . } @Entity public class Employe { @Embedded private Adresse adresse; ...
R. Grin JPA page 40
R. Grin
JPA
page 39
Restrictions
La version actuelle de JPA a plusieurs restrictions (peut-tre enleves dans une prochaine version) : n une entit ne peut possder une collection dobjets insrs n un objet insr ne peut rfrencer un autre objet insr ni avoir une association avec une entit Un objet insr ne peut tre rfrenc par plusieurs entits diffrentes
R. Grin JPA page 41
R. Grin
JPA
page 42
Exemple
@Entity public class Employe { @Embedded @AttributeOverrides({ @AttributeOverride( name="numero", column=@column(name="num")), @AttributeOverride(...) }) private Adresse adresse; ...
R. Grin JPA page 43
Exemple
@Enumerated(EnumType.STRING) private TypeEmploye typeEmploye;
R. Grin
JPA
page 46
Types temporels
Lorsqu'une classe entit a un attribut de type temporel (Calendar ou Date de java.util), il est obligatoire d'indiquer de quel type temporel est cet attribut par une annotation @Temporal Cette indication permettra au fournisseur de persistance de savoir comment dclarer la colonne correspondante dans la base de donnes : une date (un jour), un temps sur 24 heures (heures, minutes, secondes la milliseconde prs) ou un timeStamp (date + heure la microseconde prs)
R. Grin JPA page 47
R. Grin
JPA
page 48
Exemple
@Temporal(TemporalType.DATE) private Calendar dateEmb;
Tables multiples
Il est possible de sauvegarder une entit sur plusieurs tables Voir @SecondaryTable dans la spcification JPA
R. Grin
JPA
page 49
R. Grin
JPA
page 50
Schma relationnel
Dans le cas o le schma relationnel est construit automatiquement partir des annotations, il est possible de prciser des informations sur les tables gnres ou les colonnes de ces tables Par exemple, une contrainte d'unicit, ou "not null", la longueur des colonnes de type varchar, la prcision des nombres virgule, ou mme le texte entier qui permet de dfinir une colonne Voir la spcification JPA pour plus de dtails
R. Grin JPA page 51
Exemple
@Entity @Table(name="PARTICIPATION2", uniqueConstraints = @UniqueConstraint( columnNames = {"EMPLOYE_ID", "PROJET_ID"}) ) public class Participation { ... }
R. Grin JPA page 52
Principe de base
La persistance des entits nest pas transparente Une instance dentit ne devient persistante que lorsque lapplication appelle la mthode approprie du gestionnaire dentit (persist ou merge) Cette conception a t voulue par les concepteurs de lAPI par souci de flexibilit et pour permettre un contrle fin de lapplication sur la persistance des entits
page 53 R. Grin JPA page 54
R. Grin
JPA
Unit de persistance
Cest une configuration nomme qui contient les informations ncessaires lutilisation dune base de donnes Elle est associe un ensemble de classes entits
R. Grin
JPA
page 55
R. Grin
JPA
page 56
Contexte de persistance
Un contexte de persistance est un ensemble dentits qui vrifie la proprit suivante : il ne peut exister 2 entits diffrentes qui reprsentent des donnes identiques dans la base Un contexte de persistance est gr par un gestionnaire dentits qui veille ce que cette proprit soit respecte Un contexte de persistance ne peut appartenir qu une seule unit de persistance Une unit de persistance peut contenir plusieurs contextes de persistance
R. Grin JPA page 57
Contexte de persistance
Cest la responsabilit de lapplication de sassurer quune entit nappartient qu un seul contexte de persistance Sinon, 2 entits de 2 contextes de persistance diffrents pourraient correspondre des donnes identiques dans la base de donnes
R. Grin
JPA
page 58
Contexte de persistance
Quand une entit est incluse dans un contexte de persistance (persist ou merge), ltat de lentit est automatiquement sauvegard dans la base au moment de la validation (commit) de la transaction
Interface EntityManager
Elle reprsente un GE Implmentation fournie par le fournisseur de persistance
R. Grin
JPA
page 59
R. Grin
JPA
page 60
10
Types de GE
GE gr par le container (uniquement disponible dans un serveur dapplications) n dlimit par les transactions (TRANSACTION) n peut survivre une fin de transaction (EXTENDED) ; ncessite un bean session avec tat (stateful) GE gr par lapplication (seul type disponible en dehors dun serveur dapplications) ; pas dlimit par les transactions
R. Grin JPA page 61
Ce cours prsente lutilisation de JPA en dehors du container dun serveur dapplication Voir la dernire section de ce cours pour des informations sur JPA dans une serveur dapplication
R. Grin
JPA
page 62
Fabrique de GE
La classe Persistence permet dobtenir une fabrique de gestionnaire dentits par la mthode createEntityManagerFactory 2 variantes surcharges de cette mthode : n 1 seul paramtre qui donne le nom de lunit de persistance (dfinie dans le fichier persistence.xml) n Un 2me paramtre de type Map qui contient des valeurs qui vont craser les proprits par dfaut contenues dans persistence.xml
R. Grin JPA page 64
R. Grin
JPA
page 63
Mthodes de EntityManager
void persist(Object entit) <T> T merge(T entit) void remove(Object entit) <T> T find(Class<T> classeEntit, Object clPrimaire) <T> T getReference(Class<T> classeEntit, Object clPrimaire) void flush() void setFlushMode(FlushModeType flushMode)
R. Grin JPA page 65
Mthodes de EntityManager
void lock(Object entit, LockModeType lockMode) void refresh(Object entit) void clear() boolean contains(Object entit) Query createQuery(String requte) Query createNamedQuery(String nom)
R. Grin
JPA
page 66
11
Mthodes de EntityManager
Query createNativeQuery(String requte) Query createNativeQuery(String requte, Class classeRsultat) void joinTransaction() void close() boolean isOpen() EntityTransaction getTransaction()
flush
Toutes les modifications effectues sur les entits du contexte de persistance gres par le GE sont enregistres dans la BD lors dun flush du GE Au moment du flush, le GE tudie ce quil doit faire pour chacune des entits quil gre et il lance les commandes SQL adaptes pour modifier la base de donnes (INSERT, UPDATE ou DELETE)
R. Grin JPA page 68
R. Grin
JPA
page 67
flush
Un flush est automatiquement effectu au moins chaque commit de la transaction en cours Une exception TransactionRequiredException est leve si la mthode flush est lance en dehors dune transaction
flush
Soit X une des entits gre, avec une association de X vers une entit Y Si cette association est note avec cascade=persist ou cascade=all, Y est elle aussi flushe Sinon, si Y est new ou removed, une exception IllegalStateException sera leve et la transaction est invalide (rollback) Sinon, si Y est dtache et X possde lassociation, Y est flushe ; si Y est la propritaire, le comportement est indfini
R. Grin JPA page 70
R. Grin
JPA
page 69
Mode de flush
Normalement (mode FlushMode.AUTO) un flush des entits concernes par une requte est effectu avant la requte pour que le rsultat tienne compte des modifications effectues en mmoire sur ces entits Il est possible d'viter ce flush avec la mthode setFlushMode : em.setFlushMode(FlushMode.COMMIT); En ce cas, un flush ne sera lanc qu'avant un commit Il est possible de modifier ce mode pour une seule requte (voir Query)
R. Grin JPA page 71
persist
Une entit nouvelle devient une entit gre Ltat de lentit sera sauvegard dans la BD au prochain flush ou commit Aucune instruction ne sera ncessaire pour faire enregistrer au moment du commit dans la base de donnes les modifications effectues sur lentit par lapplication ; en effet le GE conserve toutes les informations ncessaires sur les entits quil gre
R. Grin JPA page 72
12
persist(A)
Si A est nouvelle, elle devient gre Si A tait dj gre, persist est ignore mais lopration persist cascade sur les entits associes si lassociation a lattribut CascadeType.PERSIST Si A est supprime, elle devient gre Si A est dtache, une IllegalArgumentException est lance Ne peut tre utilis que dans le contexte dune transaction
R. Grin JPA page 73 R. Grin
remove
Une entit gre devient supprime Les donnes correspondantes seront supprimes de la BD
JPA
page 74
remove(A)
Ignore si A est nouvelle ou supprime Si A est nouvelle, lopration cascade sur les associations qui ont lattribut CascadeType.REMOVE Si A est gre, elle devient supprime Si A est dtache, une IllegalArgumentException est lance Ne peut tre utilis que dans le contexte dune transaction
R. Grin JPA page 75
refresh
Le GE peut synchroniser avec la BD une entit quil gre en rafraichissant son tat en mmoire avec les donnes actuellement dans la BD : em.refresh(entite); Les donnes de la BD sont copies dans lentit Utiliser cette mthode pour sassurer que lentit a les mmes donnes que la BD Peut tre utile pour les transactions longues
R. Grin JPA page 76
refresh(A)
Ignore si A est nouvelle ou supprime Si A est nouvelle, lopration cascade sur les associations qui ont lattribut CascadeType.REFRESH Si A est dtache, une IllegalArgumentException est lance
find
La recherche est polymorphe : l'entit rcupre peut tre de la classe passe en paramtre ou d'une sous-classe Exemple : Article p = em.find(Article.class, 128); peut renvoyer un article de n'importe quelle sous-classe de Article (Stylo, Ramette,)
R. Grin
JPA
page 77
R. Grin
JPA
page 78
13
lock(A)
Le fournisseur de persistance gre les accs concurrents aux donnes de la BD reprsentes par les entits avec une stratgie optimiste lock ermet de modifier la manire de grer les accs concurrents une entit A Sera tudi plus loin dans la section sur la concurrence
R. Grin
JPA
page 79
R. Grin
JPA
page 81
R. Grin
JPA
page 82
merge(A)
Si A est une entit dtache, son tat est copi dans une entit gre A qui a la mme identit que A (si A nexiste pas dj, il est cr) ; merge renvoie A Si A est nouvelle, une nouvelle entit gre A' est cr et ltat de A est copi dans A Si A est dj gre, merge est ignore mais merge cascade pour tous les associations avec lattribut CascadeType.MERGE Si A est supprime, une IllegalArgumentException est lance
R. Grin JPA page 83
merge(A)
Attention, la mthode merge nattache pas A Elle retourne une entit gre qui a la mme identit dans la BD que lentit passe en paramtre mais a nest pas le mme objet
R. Grin
JPA
page 84
14
Cl primaire
Une entit doit avoir un attribut qui correspond la cl primaire dans la table associe La valeur de cet attribut ne doit jamais tre modifie par lapplication Cet attribut doit tre dfini dans lentit racine dune hirarchie dhritage (uniquement cet endroit dans toute la hirarchie dhritage) Une entit peut avoir une cl primaire composite (pas recommand)
page 85 R. Grin JPA page 86
R. Grin
JPA
Annotation
Lattribut cl primaire est dsign par lannotation @Id Pour une cl composite on utilise @EmbeddedId ou @IdClass
Type de la cl primaire
Le type de la cl primaire (ou des champs dune cl primaire compose) doit tre un des types suivants : n type primitif Java n classe qui enveloppe un type primitif n java.lang.String n java.util.Date n java.sql.Date Ne pas utiliser les types numriques non entiers
R. Grin
JPA
page 87
R. Grin
JPA
page 88
Gnration automatique de cl
Si la cl est de type numrique entier, lannotation @GeneratedValue indique que la cl primaire sera gnre automatiquement par le SGBD Cette annotation peut avoir un attribut strategy qui indique comment la cl sera gnre (il prend ses valeurs dans lnumration GeneratorType)
Types de gnration
AUTO : le type de gnration est choisi par le fournisseur de persistance, selon le SGBD (squence, table,) ; valeur par dfaut SEQUENCE : utilise une squence est utilise IDENTITY : une colonne de type IDENTITY est utilise TABLE : une table qui contient la prochaine valeur de lidentificateur est utilise On peut aussi prciser le nom de la squence ou de la table avec lattribut generator
R. Grin JPA page 90
R. Grin
JPA
page 89
15
Exemple
@Id @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "EMP_SEQ") public long getId() { return id; }
R. Grin
JPA
page 92
Cl composite
Pas recommand, mais une cl primaire peut tre compose de plusieurs colonnes Peut arriver quand la BD existe dj ou quand la classe correspond une table association (association M:N) 2 possibilits : n @IdClass n @EmbeddedId et @Embeddable
R. Grin
JPA
page 93
R. Grin
JPA
page 94
@EmbeddedId
@EmbeddedId correspond au cas o la classe entit comprend un seul attribut annot @EmbeddedId La classe cl primaire est annot par @Embeddable Le type daccs (par champs ou proprits) de la classe embeddable doit tre le mme que celui de lentit dont la cl primaire est dfinie
R. Grin JPA page 95
16
@IdClass
@IdClass correspond au cas o la classe entit comprend plusieurs attributs annots par @Id La classe entit est annote par @IdClass qui prend en paramtre le nom de la classe cl primaire La classe cl primaire nest pas annote ; ses attributs ont les mmes noms et mmes types que les attributs annots @Id dans la classe entit
R. Grin JPA page 97
Associations
JPA
page 100
Gnralits
Une association peut tre uni ou bidirectionnelle Elle peut tre de type 1:1, 1:N, N:1 ou M:N Les associations doivent tre indiques par une annotation sur la proprit correspondante, pour que JPA puisse les grer correctement
Exemple
@ManyToOne public Departement getDepartement() { ... }
R. Grin
JPA
page 101
R. Grin
JPA
page 102
17
Types utiliser
Le plus souvent Collection sera utilis Set peut tre utile pour liminer les doublons Les types concrets, par exemple HashSet ou ArrayList, ne peuvent tre utiliss que pour des entits nouvelles ; ds que lentit est gre, les types interfaces doivent tre utiliss List peut tre utilis pour conserver un ordre mais ncessite quelques prcautions
R. Grin JPA page 104
@OrderBy
Cette annotation indique dans quel ordre sont rcupres les entits associes Il faut prciser un ou plusieurs attributs qui dterminent l'ordre Chaque attribut peut tre prcis par ASC ou DESC (ordre ascendant ou descendant); ASC par dfaut Les diffrents attributs sont spars par une virgule Si aucun attribut n'est prcis, l'ordre sera celui de la cl primaire
R. Grin JPA page 106
R. Grin
JPA
page 105
Exemples
@Entity public class Departement { ... @OneToMany(mappedBy="departement") @OrderBy("nomEmploye") public List<Employe> getEmployes() { ... @OrderBy("poste DESC, nomEmploye ASC")
Associations bidirectionnelles
Le dveloppeur est responsable de la gestion correcte des 2 bouts de lassociation Par exemple, si un employ change de dpartement, les collections des employs des dpartements concerns doivent tre modifies Un des 2 bouts est dit propritaire de lassociation
R. Grin
JPA
page 107
R. Grin
JPA
page 108
18
Bout propritaire
Pour les associations autres que M:N ce bout correspond la table qui contient la cl trangre qui traduit lassociation Pour les associations M:N le dveloppeur peut choisir arbitrairement le bout propritaire Lautre bout (non propritaire) est qualifi par lattribut mappedBy qui donne le nom de lattribut dans le bout propritaire qui correspond la mme association
R. Grin JPA page 109
Exemple
Dans la classe Employe :
@ManyToOne public Departement getDepartement() { return departement; }
R. Grin
JPA
page 110
Annotation @JoinColumn
Cette annotation donne le nom de la colonne cl trangre qui reprsente l'association dans le modle relationnel Elle doit tre mise du ct propritaire Sans cette annotation, le nom est dfini par dfaut : <entit_but>_<cl_primaire_entit_but>
Exemple
Pour l'association qui dtermine le dpartement d'un employ Par dfaut, la colonne cl trangre place dans la table EMPLOYE s'appellera Departement_ID Pour changer ce nom (dans la classe Employe) :
@ManyToOne @JoinColumn(name="DEPT_ID") public Departement getDepartement() {
R. Grin JPA page 112
R. Grin
JPA
page 111
Pas si simple
Maintenir une cohrence automatique des valeurs persistantes nest pas si simple en cas de persistance par transitivit Par exemple, que se passe-t-il si un objet supprim est rfrenc par un autre objet ?
R. Grin
JPA
page 114
19
Le choix de JPA
Par dfaut, JPA neffectue pas de persistance par transitivit Ce comportement permet plus de souplesse, et un meilleur contrle de lapplication sur ce qui est rendu persistant Pour que les objets associs un objet persistant deviennent automatiquement persistants, il faut lindiquer dans les informations de mapping de lassociation (attribut cascade)
R. Grin JPA page 115
Attribut cascade
Les annotations qui dcrivent les associations entre objets peuvent avoir un attribut cascade pour indiquer que certaines oprations de GE doivent tre appliques aux objets associs Ces oprations sont PERSIST, REMOVE, REFRESH et MERGE ; ALL correspond toutes ces oprations Par dfaut, aucune opration nest applique transitivement
R. Grin JPA page 116
Exemples
@OneToMany( cascade=CascadeType.PERSIST) @OneToMany( cascade={CascadeType.PERSIST, CascadeType.MERGE})
Association 1:1
Annotation @OneToOne Reprsente par une cl trangre dans la table qui correspond au ct propritaire Exemple :
@OneToOne public Adresse getAdresse() { }
R. Grin
JPA
page 117
R. Grin
JPA
page 118
Exemple
class Employe { ... @ManyToOne public Departement getDepartement() { ... } } class Departement { ... @OneToMany(MappedBy="departement") public List<Employe> getEmployes() { ... } }
R. Grin JPA page 120
R. Grin
JPA
page 119
20
Cas particulier
Une association monodirectionnelle 1:N est traduite pas une table association Cette faon de faire vite d'avoir une cl trangre dans la table qui reprsente le ct N (comme cest le cas si lassociation est bidirectionnelle) alors que la navigation nest pas possible partir de ce ct N
Association M:N
Annotation @ManyToMany Reprsente par une table association
R. Grin
JPA
page 121
R. Grin
JPA
page 122
R. Grin
JPA
page 123
R. Grin
JPA
page 124
@JoinTable
Donne des informations sur la table association qui va reprsenter lassociation Attribut name donne le nom de la table Attribut joinColumns donne les noms des colonnes de la table qui rfrencent les cls primaires du ct propritaire de lassociation Attribut inverseJoinColumns donne les noms des colonnes de la table qui rfrencent les cls primaires du ct qui nest pas propritaire de lassociation
R. Grin JPA page 125
R. Grin
JPA
page 126
21
R. Grin
JPA
Exemple - 1 identificateur
Association entre les employs et les projets Cas d'un identificateur unique : la classe association contiendra les attributs id (int), employe (Employe), projet (Projet) et fonction (String) L'attribut id est annot par @Id Les attributs employe et projet sont annots par @ManyToOne Une contrainte d'unicit sur (EMPLOYE_ID, PROJET_ID) traduira le fait qu'un employ ne peut avoir 2 fonctions dans un mme projet
page 129 R. Grin JPA page 130
R. Grin
JPA
22
R. Grin
JPA
page 136
Classe ParticipationId
public class ParticipationId implements Serializable { private int employeId; private int projetId; public int getEmployeId() { ... } public void setEmployeId(int employeId) { ... } public int getProjetId() { ... } public void setProjetId(int projetId) { ... } // Redfinir aussi equals et hasCode
R. Grin JPA page 137
23
EAGER ou LAZY
JPA laisse le choix de rcuprer ou non immdiatement les entits associes, suivant les circonstances Il suffit de choisir le mode de rcupration de lassociation (LAZY ou EAGER) Une requte sera la mme, quel que soit le mode de rcupration Dans le mode LAZY les donnes associes ne sont rcupres que lorsque cest vraiment ncessaire
R. Grin JPA page 139
24
Exemple
Les employs dun dpartement peuvent tre enregistrs dans une map dont les cls sont les noms des employs (on suppose que 2 employs nont pas le mme nom)
public class Departement { ... @OneToMany(mappedBy="nom") public Map<String,Employe> getEmployes(){ ... }
R. Grin
JPA
page 145
R. Grin
JPA
page 146
Stratgies
A ce jour, les implmentations de JPA doivent obligatoirement offrir 2 stratgies pour la traduction de lhritage : n une seule table pour une hirarchie dhritage (SINGLE_TABLE) n une table par classe ; les tables sont jointes pour reconstituer les donnes (JOINED) La stratgie une table distincte par classe concrte est seulement optionnelle (TABLE_PER_CLASS)
page 147 R. Grin JPA page 148
Hritage
R. Grin
JPA
Exemple
A mettre dans la @Entity classe racine de @Inheritance(strategy= la hirarchie InheritanceType.SINGLE_TABLE) public abstract class Personne {...} @Entity Employe par dfaut @DiscriminatorValue("E") public class Employe extends Personne { ... }
R. Grin JPA page 150
R. Grin
JPA
page 149
25
Nom de la table
Si on choisit la stratgie une seule table pour une arborescence dhritage la table a le nom de la table associe la classe racine de la hirarchie
R. Grin
JPA
page 151
Exemple
@Entity @Inheritance @DiscriminatorColumn( name="TRUC", discriminatorType="STRING", length=5) public class Machin { }
R. Grin
JPA
page 154
Valeur discriminatrice
Chaque classe est diffrencie par une valeur de la colonne discriminatrice Cette valeur est passe en paramtre de lannotation @DiscriminatorValue Par dfaut cette valeur est le nom de la classe
R. Grin
JPA
26
Exemple
@Entity @Inheritance(strategy= InheritanceType.JOINED) public abstract class Personne {...} @Entity @DiscriminatorValue("E") public class Employe extends Personne { ... }
R. Grin
JPA
page 157
Exemple
@Entity @Inheritance(strategy= InheritanceType.TABLE_PER_CLASS) public abstract class Personne {...} @Entity @Table(name=EMPLOYE) public class Employe extends Personne { ... }
Entit abstraite
Une classe abstraite peut tre une entit (annote par @Entity) Son tat sera persistant et sera utilis par les sous-classes entits Comme toute entit, elle pourra dsigner le type retour dune requte (query) pour une requte polymorphe
R. Grin
JPA
page 159
R. Grin
JPA
page 160
Complments
Lannotation @Entity ne shrite pas Les sous-classes entits dune entit doivent tre annote par @Entity Une entit peut avoir une classe mre qui nest pas une entit ; en ce cas, ltat de cette classe mre ne sera pas persistant
R. Grin
JPA
page 161
R. Grin
JPA
page 162
27
R. Grin
JPA
page 163
R. Grin
JPA
page 164
Requtes - JPQL
getReference
getReference renvoie une rfrence vers une entit, sans que cette entit ne soit ncessairement initialise Le plus souvent il vaut mieux utiliser find
getReference
getReference peut tre (rarement) utilise pour amliorer les performances quand une entit non initialise peut tre suffisante, sans que lentit entire soit retrouve dans la base de donnes Par exemple, pour indiquer une association dont le but est unique (OneToOne ou ManyToOne) :
Departement dept = em.getReference(Departement.class, 10); Employe emp.setDepartement(dept);
R. Grin
JPA
page 167
R. Grin
JPA
page 168
28
Langage JPQL
Le langage JPQL (Java Persistence Query Language) permet de dcrire ce que lapplication recherche Il ressemble beaucoup SQL
R. Grin
JPA
page 170
Alias
Le texte des requtes utilise beaucoup les alias de classe Les attributs des classes doivent tre prfixs par les alias Une erreur frquente du dbutant est doublier les alias en prfixe
R. Grin
JPA
page 171
R. Grin
JPA
page 172
Exemples de requtes
select e from Employe as e select e.nom, e.salaire from Employe e select e from Employe e where e.departement.nom = 'Direction' select d.nom, avg(e.salaire) from Departement d join d.employes e group by d.nom having count(d.nom) > 5
Type du rsultat
Lexpression de la clause select peut tre n une (ou plusieurs) expression entit , par exemple un employ (e par exemple) n une (ou plusieurs) expression valeur , par exemple le nom et le salaire dun employ (e.nom par exemple) Lexpression ne peut tre une collection (d.employes par exemple), bien que TopLink le permette !
R. Grin JPA page 174
R. Grin
JPA
page 173
29
R. Grin
JPA
page 175
Exemple
texte = "select e.nom, e.salaire " + " from Employe as e"; query = em.createQuery(texte); List<Object[]> liste = (List<Object[]>)query.getResultList(); for (Object[] info : liste) { System.out.println(info[0] + " gagne " + info[1]); }
R. Grin
JPA
page 177
R. Grin
JPA
page 178
Interface Query
Reprsente une requte Une instance de Query (dune classe implmentant Query) est obtenue par les mthodes createQuery, createNativeQuery ou createNamedQuery de linterface EntityManager
R. Grin
JPA
page 179
30
Types temporels
On a vu que les 2 types java temporels du paquetage java.util (Date et Calendar) ncessitent une annotation @Temporal Ils ncessitent aussi un paramtre supplmentaire pour la mthode setParameter
R. Grin
JPA
page 181
R. Grin
JPA
page 182
Exemple
@Temporal(TemporalType.DATE) private Calendar dateEmb; em.createQuery("select e from employe e" + " where e.dateEmb between ?1 and ?2") .setParameter(1, debut, TemporalType.DATE) .setParameter(2, fin, TemporalType.DATE) .getResultList();
Types de requte
Requtes dynamiques dont le texte est donne en paramtre de createQuery Requtes natives particulires un SGBD (pas portables) ; requte SQL (pas JPQL) avec tables et colonnes (pas classes et attributs) Requtes nommes dont le texte est donne dans une annotation de lentit concerne et dont le nom est pass en paramtre de createNamedQuery ; une requte nomme peut tre dynamique ou native
R. Grin JPA page 184
R. Grin
JPA
page 183
31
Exemples
Query query = em.createQuery( "select e from Employe as e " + "where e.nom = ?1"); query.setParameter(1, "Dupond"); Query query = em.createQuery( "select e from Employe as e " + "where e.nom = :nom"); query.setParameter("nom", "Dupond");
Mode de flush
Normalement (mode FlushMode.AUTO) un flush des entits concernes par une requte est effectu avant la requte pour que le rsultat tienne compte des modifications effectues en mmoire sur ces entits Pour une requte il est possible d'viter ce flush avec la mthode setFlushMode : query.setFlushMode(FlushMode.COMMI T);
R. Grin
JPA
page 187
R. Grin
JPA
page 188
R. Grin
JPA
page 189
R. Grin
JPA
page 190
R. Grin
JPA
page 191
R. Grin
JPA
page 192
32
Expression de chemin
Les requtes peuvent contenir des expressions de chemin pour naviguer entre les entits en suivant les associations dclares dans le modle objet (les annotations @OneToOne, @OneToMany, ) La notation pointe est utilise
Exemples
Si e est un alias pour Employe, n e.departement dsigne le dpartement dun employ n e.projets dsigne la collection de projets auxquels participe un employ
select e.nom from Employe as e where e.departement.nom = 'Qualit'
R. Grin
JPA
page 193
R. Grin
JPA
page 194
distinct
Dans une clause select, indique que les valeurs dupliques sont limines (la requte ne garde quune seule des valeurs gales) Exemple : select distinct e.departement from Employe e
new
Il est possible de renvoyer des instances dune classe dont le constructeur prend en paramtre des informations rcupres dans la base de donnes La classe doit tre dsigne par son nom complet (avec le nom du paquetage) Exemple :
select new p1.p2.Classe(e.nom, e.salaire) from Employe e
R. Grin
JPA
page 195
R. Grin
JPA
page 196
Exemple
select d.nom, avg(e.salaire) from Departement d join d.employes e group by d.nom having count(d.nom) > 3
R. Grin
JPA
page 197
R. Grin
JPA
page 198
33
having
Restriction : la condition doit porter sur lexpression de regroupement ou sur une fonction de regroupement portant sur lexpression de regroupement Par exemple, la requte suivante provoque une exception :
select d.nom, avg(e.salaire) from Departement d join d.employes e group by d.nom having avg(e.salaire) > 1000
R. Grin JPA page 199
Sous-requte (1)
Les clauses where et having peuvent contenir des sous-requtes Exemple :
select e from Employe e where e.salaire >= ( select e2.salaire from Employe e2 where e2.departement = 10)
R. Grin
JPA
page 200
Sous-requte (2)
{ALL | ANY | SOME} (sous-requte) fonctionne comme dans SQL Exemple :
select e from Employe e where e.salaire >= ALL ( select e2.salaire from Employe e2 where e2.departement = e.departement)
Sous-requte synchronise
Une sous-requte peut tre synchronise avec une requte englobante Exemple :
select e from Employe e where e.salaire >= ALL ( select e2.salaire from Employe e2 where e2.departement = e.departement)
R. Grin
JPA
page 201
R. Grin
JPA
page 202
Sous-requte - exists
[not]exists fonctionne comme avec SQL Exemple :
select emp from Employe e where exists ( select ee from Employe ee where ee = e.epouse)
R. Grin
JPA
page 203
R. Grin
JPA
page 204
34
Exemple
select e.nom, e.departement.nom, e.superieur.departement.nom from Employe e
Contre-exemple
d.employes.nom est interdit car d.employes est une collection Pour avoir les noms des employs dun dpartement, il faut utiliser une jointure
R. Grin
JPA
page 205
R. Grin
JPA
page 206
Jointure
Une jointure permet de combiner plusieurs entits dans un select Rappel : il est possible dutiliser plusieurs entits dans une requte grce la navigation Une jointure est le plus souvent utilise pour rsoudre les cas (interdit par JPA) o n lexpression du select serait une collection n la navigation partirait dune collection
R. Grin JPA page 207
Types de jointures
Il existe plusieurs types de jointures : n jointure interne (jointure standard join) n jointure externe (outer join) n jointure avec rcupration de donnes en mmoire (join fetch)
R. Grin
JPA
page 208
Exemple
Si on veut tous les employs dun dpartement, la requte suivante nest pas permise par la spcification JPA (bien que TopLink lautorise) :
select d.employes from Departement d where d.nom = 'Direction'
Autres exemples
select e.nom from Departement d join d.employes e where d.nom = 'Direction' select e.nom, parts.projet.nom from Employe e join e.participations parts select e.nom, d.nom from Employe e, Departement d where d = e.departement select e, p from Employe e join e.participations parts join parts.projet p
R. Grin JPA page 210
35
Jointure externe
select e, d from Employe e left join e.departement d
join fetch
Permet dviter le problme des N + 1 selects Lentit plac droite de fetch join sera cre en mmoire en mme temps que lentit de la clause select Le select SQL gnr sera une jointure externe qui rcuprera les donnes de toutes les entits associes en mme temps que les donnes des entits principales de la requte
R. Grin JPA page 212
R. Grin
JPA
page 211
Exemple
select e from Employe e join fetch e.departement
Exemple
String texteQuery = "select e " + " from Employe as e " + " join fetch e.participations"; Query query = em.createQuery(texteQuery); listeEmployes = (List<Employe>)query.getResultList();
Cette requte rcuprera tous les employs mais, en plus, lappel de la mthode getDepartement() ne provoquera aucune interrogation de la base de donnes puisque le join fetch aura dj charg tous les dpartements des employs Lexemple suivant prcharge les collections de participations aux projets
R. Grin JPA page 213
R. Grin
JPA
page 214
Fonctions
Fonctions de chanes de caractres : concat, substring, trim, lower, upper, length, locate (localiser une sous-chane dans une autre) Fonctions arithmtiques : abs, sqrt, mod, size (dune collection) Fonctions de date : current_date, current_time, current_timestamp Fonctions de regroupement : count, max, min, avg Pour plus dinformations, consultez la spcification JPA
R. Grin JPA page 216
36
Exemples
select d from Departement where e.employes is empty select e from Employe e where :projet member of e.participations.projet
R. Grin
JPA
page 218
En effet, il est interdit de composer une expression de chemin en partant dune expression qui dsigne une collection (f.lignes)
Lautre solution, in , une ancienne syntaxe hrite dEJB 2, nest pas recommande
R. Grin
JPA
page 219
R. Grin
JPA
page 220
Pagination du rsultat
Query setMaxResults(int n) : indique le nombre maximum de rsultats retrouver Query setFirstResult(int n) : indique la position du 1er rsultat retrouver (numrot partir de 0)
R. Grin
JPA
page 221
R. Grin
JPA
page 222
37
Utilit
Pour les performances il est parfois mauvais de charger toutes les donnes modifier dans des instances dentits En ce cas, EJBQL permet de modifier les donnes de la base directement, sans crer les entits correspondantes
R. Grin
JPA
page 223
R. Grin
JPA
page 224
Cas dutilisation
Si on veut augmenter de 5% les 1000 employs de lentreprise il serait mauvais de rcuprer dans 1000 instances les donnes de chaque employs, de modifier le salaire de chacun, puis de sauvegarder les donnes Un simple ordre SQL
update employe set salaire = salaire * 1.05
Exemple
em.getTransaction().begin(); String ordre = "update Employe e " + " set e.salaire = e.salaire * 1.05"; Query q = em.createQuery(ordre); int nbEntiteModifiees = q.executeUpdate(); em.getTransaction().commit();
R. Grin
JPA
page 225
R. Grin
JPA
page 226
Syntaxe
Les ordres de modification en volume rfrencent les classes et les proprits des classes mais ils ne crent aucune entit en mmoire et ils ne mettent pas jour les entits dj prsentes en mmoire update Entite as alias set alias.prop1 = val1, alias.prop2 = val2, where condition La condition peut tre aussi complexe que la condition dun select
R. Grin JPA page 227
Remarques
Les modifications doivent tre faites dans une transaction Le plus souvent il faut isoler le lancement de ces oprations dans une transaction part, ou au moins excuter ces oprations au dbut dune transaction avant la rcupration dans la base dentits touches par lopration En effet, les entits en mmoire ne sont pas modifies par lopration et elles ne correspondront alors donc plus aux nouvelles valeurs modifies dans la base de donnes
R. Grin JPA page 228
38
Exceptions
Types dexception
EntityNotFoundException EntityExistsException NonUniqueResultException NoResultException TransactionRequiredException RollbackException OptimisticLockException
Transaction
R. Grin
JPA
page 231
R. Grin
JPA
page 232
2 types de transactions
Les transactions locales une ressource, fournies par JDBC sont attaches une seule base de donnes Les transactions JTA, avec plus de fonctionnalits que les transactions JDBC, en particulier elles peuvent travailler avec plusieurs bases de donnes
R. Grin
JPA
page 233
R. Grin
JPA
page 234
39
EntityTransaction
En dehors dun serveur dapplications, une application doit utiliser linterface javax.persitence.EntityTransaction pour travailler avec des transactions locales une ressource Une instance de EntityTransaction peut sobtenir par la mthode getTransaction() de EntityManager
R. Grin
JPA
page 236
EntityTransaction
public interface EntityTransaction { public void begin(); public void commit(); public void rollback(); public void setRollbackOnly(); public boolean getRollbackOnly(); public void isActive(); }
Exemple
EntityManager em; ... try { em.getTransaction().begin() ... em.getTransaction().commit(); } finally { em.close(); }
page 237 R. Grin JPA page 238
R. Grin
JPA
Rollback (1)
En cas de rollback, n rollback dans la base de donnes n le contexte de persistance est vid ; toutes les entits deviennent dtaches
Rollback (2)
Les instances dentits Java gardent les valeurs quelles avaient au moment du rollback Mais ces valeurs sont le plus souvent fausses Il est donc rare dutiliser ces entits en les rattachant par un merge un GE Le plus souvent il faut relancer des requtes pour rcuprer des entits avec des valeurs correctes
R. Grin
JPA
page 239
R. Grin
JPA
page 240
40
Modifications et commit
Les modifications effectues sur les entits gres sont enregistres dans la base de donnes au moment dun commit Les modifications sont enregistres dans la base, mme si elles ont t effectues avant le dbut de la transaction (avant le tx.begin())
R. Grin
JPA
page 241
R. Grin
JPA
page 242
Concurrence
R. Grin
JPA
page 243
R. Grin
JPA
page 244
GE et threads
Une fabrique de GE peut tre utilise sans problme par plusieurs threads Mais un GE ne doit tre utilis concurremment que par un seul thread
Entits et threads
Les entits ne sont pas prvues pour tre utilises par plusieurs threads en mme temps Si a doit tre le cas, lapplication doit prendre toutes ses prcautions pour viter les problmes Cest aussi le rle de lapplication dempcher quune entit ne soit gre par plusieurs GE en mme temps Le rle du fournisseur de persistance nintervient pas pour ces cas
R. Grin JPA page 246
R. Grin
JPA
page 245
41
Concurrence BD
Le fournisseur de persistance peut apporter automatiquement une aide pour viter les problmes daccs concurrents aux donnes de la BD, pour les entits gres par un GE
R. Grin
JPA
page 247
R. Grin
JPA
page 248
Gestion de la concurrence
Par dfaut, le fournisseur de persistance gre les problmes daccs concurrents aux entits gres par un GE avec une stratgie optimiste
@version
Annote un attribut dont la valeur reprsentera un numro de version (incrment chaque modification) pour lentit et sera utilise pour savoir si ltat dune entit a t modifie entre 2 moments diffrents (stratgie optimiste) Lattribut doit tre de type int, Integer, short, Short, long, Long ou java.sql.TimeStamp (si possible, viter ce dernier type) Lapplication ne doit jamais modifier un tel attribut (modifi par JPA)
R. Grin JPA page 250
R. Grin
JPA
page 249
Exemple
@Version private int version;
Entit versionne
Cest une entit qui possde un attribut qui possde lannotation @version (ou le tag correspondant dans les fichiers XML)
R. Grin
JPA
page 251
R. Grin
JPA
page 252
42
lock(A, mode)
Sert protger une entit contre les accs concurrents pour les cas o la protection offerte par dfaut par le fournisseur ne suffit pas Cette entit doit tre versionne (sinon, le traitement nest pas portable)
Modes de blocage
Lnumration LockModeType (paquetage javax.persistence) dfinit 2 modes READ : les autres transactions peuvent lire lentit mais ne peuvent pas la modifier WRITE : comme READ, mais en plus lattribut de version est incrment, mme si lentit na pas t modifie (utilit explique dans les transparents suivants)
R. Grin
JPA
page 253
R. Grin
JPA
page 254
READ
Empche les lectures non rptables sur les donnes de la BD associes lentit Le fournisseur de persistance peut choisir une stratgie pessimiste (du type select for update ) ou optimiste
READ
Le blocage rel peut ntre effectu quau moment du flush ou du commit, quelle que soit lemplacement du read dans le code Java Sil y a un problme, une exception OptimisticLockException peut tre lance
R. Grin
JPA
page 255
R. Grin
JPA
page 256
WRITE
vite en quelque sorte les problmes de lignes fantmes avec les associations qui concernent une entit En effet, le fournisseur de persistance incrmente automatiquement le numro de version si une entit est modifie mais pas si les liens des associations qui partent de lentit sont modifies
R. Grin
JPA
page 257
R. Grin
JPA
page 258
43
Niveau disolation
Le fournisseur suppose que le SGBD gre la base de donnes avec un niveau disolation READ COMMITED (voir cours sur les BD)
Entit dtache
R. Grin
JPA
page 261
R. Grin
JPA
page 262
Cas dutilisation
Le serveur dapplication rcupre des donnes dans la BD Ces donnes sont montres lutilisateur et celui-ci peut les modifier Les modification sont repasses au serveur et enregistres dans la BD Les entits dtaches facilitent limplmentation dun tel cas dutilisation
EJB 2.0
Dans la norme EJB 2.0, les donnes de la BD taient enregistres dans un objet EJB entit Le problme tait quun objet entit ne pouvait exister que dans lenvironnement du serveur dapplication Les donnes tait donc souvent passes au client sous forme de DTO (pour viter de nombreux appels distants aux EJB entits, qui sont coteux)
R. Grin JPA page 264
R. Grin
JPA
page 263
44
EJB 3.0
Plus ce problme dans la norme EJB 3.0 Les entits peuvent tre dtaches de leur contexte de persistance dorigine et rattaches par la suite
EJB 3.0
Une fois dtaches les entits peuvent tre passes sans problme la couche cliente Les modifications effectues par lutilisateur peuvent tre enregistres dans lentit dtache Lentit peut ensuite tre rattache un GE et les modifications sont alors enregistres dans la base de donnes
R. Grin
JPA
page 265
R. Grin
JPA
page 266
Rattachement
La mthode merge de EntityManager permet dobtenir une entit gre partir dune entit dtache Sa signature : <T> T merge(T entit) Attention, lentit passe en paramtre nest pas rattache ; cest lentit renvoye par la mthode merge qui est rattache ; cette entit a le mme tat et la mme cl primaire que lentit passe en paramtre
R. Grin JPA page 267
Exemples de dtachement
Un servlet peut dcider denregistrer des entits dans une session dutilisateur ; cette session peut tre srialise par un conteneur de servlet (et les entits sont alors dtaches) Une application peut viter lutilisation de DTO en transfrant les donnes entre les clients et le serveur dans des objets dtachs, vitant ainsi des recopies inutiles
R. Grin JPA page 268
R. Grin
JPA
page 269
45
R. Grin
JPA
R. Grin
JPA
page 273
R. Grin
JPA
page 274
R. Grin
JPA
page 275
R. Grin
JPA
page 276
46
Conflit de concurrence
Si les donnes de la BD associe un objet dtach ont t modifies depuis le dtachement de lobjet, merge lance une exception, ou le commit chouera Tout se passe donc comme si un conflit de concurrence avait t dtect (avec une stratgie optimiste)
Dtachement automatique
Quelques situations provoquent un dtachement automatique des entits gres : n Aprs un commit si le contexte de persistance est limit la transaction (avec un serveur dapplications) n Aprs un rollback n Aprs un clear du GE n Aprs la fermeture du GE n Aprs le passage par valeur de lentit avec une mthode remote
R. Grin JPA page 278
R. Grin
JPA
page 277
Associations
X entit dtache ; association entre X et Y Ltat de Y peut tre disponible dans ces cas : n Y a t retrouv par find Y a t retrouve par une requte avec une clause join fetch n une proprit de Y non cl primaire a dj t accde par lapplication n Y est navigable depuis une entit disponible avec lassociation marque fetch=EAGER
n
R. Grin JPA page 279 R. Grin
Optimisations
JPA
page 280
Les performances dune application peuvent tre grandement amliores par n un choix adapt du mode de rcupration des entits associes n lutilisation doprations de modifications de grandes quantits de donnes sans cration dentits
Callback
R. Grin
JPA
page 281
R. Grin
JPA
page 282
47
Mthodes callback
Des mthodes peuvent tre annotes pour indiquer quelles seront appeles par le fournisseur de persistance quand une entit passera dans une nouvelle tape de son cycle de vie Ces mthodes peuvent appartenir une classe entit (entity ou classe mre mapped ) ou une classe couteur
Types de mthode
@PrePersist : quand persist (ou merge) sest termin avec succs @PostPersist : aprs linsertion dans la BD @PreRemove : quand remove est appel @PostRemove : aprs suppression dans la BD @PreUpdate : avant modification dans la BD @PostUpdate : aprs modification dans la BD @PostLoad : aprs la lecture des donnes de la BD pour construire une entit
R. Grin JPA page 284
R. Grin
JPA
page 283
Fichier XML
Les mthodes callback peuvent aussi tre indiques dans un fichier XML Un fichier XML peut indiquer des mthodes callback par dfaut qui seront appeles pour toutes les entits
R. Grin
JPA
page 285
R. Grin
JPA
page 286
R. Grin
JPA
page 288
48
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version= "1.0" > <persistence-unit name="Employes" transaction-type="RESOURCE_LOCAL"> <class>p1.Employe</class> <class>p1.Dept</class> <properties> . . . <! Voir transparent suivant--> </properties> </persistence-unit> </persistence>
R. Grin JPA page 289
Section properties
La section properties dpend du fournisseur des fonctionnalits dcrites dans la spcification JPA Elle contient les informations pour la connexion mais aussi dautres informations pour le logging ou la cration automatique des tables si elle nexistent pas dj ; il faut consulter la documentation du fournisseur
R. Grin
JPA
page 290
R. Grin
JPA
page 292
Exemple
<properties> . . . <property name="toplink.ddl-generation" value="drop-and-create-tables"/> </properties>
R. Grin
JPA
page 294
49
toplink.ddl-generation.output-mode indique ce qui sera fait avec les fichiers DDL Valeurs possibles : n sql-script gnre les fichiers mais ne les excute pas n database excute les ordres DDL mais ne gnre pas les fichiers n both gnre les fichiers et les excute (valeur par dfaut)
R. Grin JPA page 295
Proprit toplink.applicationlocation indique le nom du rpertoire qui contiendra les fichiers contenant les ordres DDL de cration et de suppression des tables (le rpertoire courant par dfaut)
R. Grin
JPA
page 296
logging (1)
toplink.create-ddl-jdbc-file-name indique le nom du fichier qui contiendra les ordres de cration des tables ; par dfaut, createDDL.jdbc toplink.drop-ddl-jdbc-file-name idem pour la suppression des tables ; par dfaut, dropDDL.jdbc La proprit toplink.logging.level peut avoir les valeurs n OFF : aucune information n SEVERE : uniquement les erreurs n WARNING : les avertissements (et les erreurs) n INFO (valeur par dfaut) : assez peu
dinformation en plus
n
R. Grin
JPA
page 297
R. Grin
JPA
page 298
logging (2)
n
Fichiers XML
R. Grin
JPA
page 299
R. Grin
JPA
page 300
50
Exemple
<persistence-unit name="xxxx"> ... <mapping-file>META-INF/queries.xml </mapping-file> <mapping-file>META-INF/entities.xml </mapping-file> </persistence-unit>
R. Grin
JPA
page 301
R. Grin
JPA
page 302
La fin de ce support concerne les serveurs dapplication et nest donne qu titre de rfrence pour ceux qui utiliseront un tel serveur Le contenu ne fait pas partie du programme demand lexamen
R. Grin
JPA
page 305
R. Grin
JPA
page 306
51
Types de GE (1)
GE gr par le container (uniquement disponible dans un serveur dapplications) GE gr par lapplication (seul type disponible en dehors dun serveur dapplications) ; pas dlimit par les transactions
R. Grin
JPA
page 307
R. Grin
JPA
page 308
Types de GE (2)
Un GE gr par le container peut tre d'un des 2 types suivants : n dlimit par les transactions (TRANSACTION ; c'est le type par dfaut) n peut survivre une fin de transaction (EXTENDED) ; ncessite un bean session avec tat (stateful)
GE gr par le container
Le contexte de persistance est inject par le serveur dapplication :
@PersistenceContext(unitName="Xxxxx")
Avec un serveur dapplications, par dfaut la dure de vie dun contexte de persistance est la transaction : il est ferm quand la transaction se termine
R. Grin
JPA
page 309
R. Grin
JPA
page 310
Ce type de GE nest disponible que dans un bean session avec tat (stateful) ; il nest pas disponible dans un bean session sans tat (stateless)
R. Grin JPA page 311
R. Grin
JPA
page 312
52
Transactions
Une requte peut tre lance en dehors de toute transaction Dans le cas o le contexte de persistance est limit une transaction, les entits seront dtaches (non gres par un GE)
R. Grin
JPA
page 314
Types de transactions
R. Grin
JPA
R. Grin
JPA
page 318
53
Un principe
Pour que tout se passe bien, tous les appels de mthodes des GE durant une mme transaction doivent utiliser le mme contexte de persistance Sinon, des modifications effectues sur des entits durant la transaction risquent dtre perdues par la suite dans la transaction JPA facilite l'application de ce principe (voir transparent suivant)
R. Grin JPA page 320
R. Grin
JPA
page 319
R. Grin
JPA
page 322
Propagation de contexte
Pour faciliter la tche du dveloppeur, les transactions JTA permettent la propagation de contexte pour les GE grs par le container Cette propagation de contexte peut occasionner des collisions de contexte dans certaines situations dans lesquelles des beans sessions avec tat sont impliqus Lhritage de contexte limite les possibilits de conflit
R. Grin JPA page 323
Dfinition
Association dun contexte de persistance avec une transaction JTA : le contexte de persistance est li la transaction ; le contexte devient le contexte actif li la transaction Cette association va permettre au container de retrouver un contexte de persistance en interrogeant la transaction, et donc de permettre la propagation de contexte
R. Grin JPA page 324
54
Dfinition
Un contexte de persistance peut tre propag durant une transaction JTA sil est utilis par des GEs grs par le container Ce contexte est alors utilis tour de rle durant la transaction par les GEs Cette propagation sappelle une propagation de contexte Quand un GE reoit un message, il vrifie sil existe un contexte propag ; si cest le cas, il utilise celui-ci, sinon il en cre un nouveau
R. Grin JPA page 325
Avantage de la propagation
Les modifications non encore enregistres dans la base (elles le seront seulement au commit de la transaction), mais enregistres dans le contexte de persistance, sont disponibles durant toute la transaction, quel que soit lemplacement du code plac dans la transaction
R. Grin
JPA
page 326
Conflit de contextes
La propagation de contexte ne fonctionne pas lors de lappel dune mthode dun bean session avec tat (stateful) depuis un autre bean En effet, une bean session avec tat ne peut travailler quavec un seul contexte et ne peut accepter de travailler avec un autre contexte propag Une exception est leve Voir la spcification JPA pour plus de dtails
R. Grin JPA page 327
Hritage de contexte
Une exception pour la collision de contexte : un bean avec tat cr par un autre bean avec tat hrite du contexte de ce bean si les 2 beans utilisent un contexte de persistance tendu Ainsi des appels de mthodes pourront se faire entre les 2 beans sans collision de contexte
R. Grin
JPA
page 328
Synchronisation
Il est possible de synchroniser plusieurs contextes de persistance grs par lapplication avec une mme transaction JTA Mais un seul contexte gr par le container peut tre synchronis avec une transaction JTA
R. Grin
JPA
page 329
R. Grin
JPA
page 330
55
joinTransaction
Lorsquun GE est cr explicitement par lapplication (il nest pas gr par le container), 2 cas : n si une transaction JTA est dj active, le contexte du GE est synchronis avec la transaction n sinon le contexte peut manuellement tre synchronis avec la transaction par la mthode joinTransaction() de EntityManager
R. Grin JPA page 332
R. Grin
JPA
page 331
Bibliographie
Toplink :
http://www.oracle.com/technology/products/ias/t oplink/jpa/index.html
R. Grin
JPA
page 333
R. Grin
JPA
page 334
Livre
Pro EJB 3 JPA de Mike Keith et Merrick Schincariol Edition Apress (en anglais)
Kodo :
http://edocs.bea.com/kodo/docs40/full/html/ejb3_overvi ew.html
R. Grin
JPA
page 335
R. Grin
JPA
page 336
56