Vous êtes sur la page 1sur 18

JDO - Persistance des donnes

1. Introduction

1.1. Quest-ce que JDO (Java Data Object)


JDO offre une approche oriente objet et standardise pour la persistance des objets Java. Au contraire de JDBC, orient base de donnes relationnelle, JDO cache les difficults lies aux diffrences entre le monde objet et le monde relationnel. Cela permet au support des donnes dtre un SGBD relationnel, objet ou XML, ou utiliser toute autre forme denregistrement des donnes. De plus, les modifications apporter au code sont minimes pour rendre des objets persistants. Les classes du domaine (celles qui correspondent aux entits qui seront persistantes) peuvent tre crites exactement comme si elles ntaient pas persistantes ; la persistance des applications e st le plus souvent transparente (aucune ligne de code ne lindique).

1.2. Composants principaux


Une application ncessitant des donnes persistantes comprend plusieurs composants principaux et essentiels son bon fonctionnement : Une base de donnes dans laquelle sont enregistrs des objets de 2 types : o persistants (correspondent des donnes de la base), o phmres (transients), non persistants, Un gestionnaire de persistance gre la persistance des objets persistants, Des mta-donnes, enregistres dans un fichier XML, dcrivent les classes des objets persistants.

2.Instance JDO
La classe dune instance persistante, appele instance JDO, doit implmenter linterface javax.jdo.spi.PersistenceCapable .Une instance dune telle classe peut ne pas tre pe rsistante. Elle le sera seulement si elle est passe en paramtre de la mthode makePersistent() de la classe PersistenceManager ou si elle est rfrence par une instance persistante.

2.1.Persistance par rfrence


JDO utilise la persistance par rfrence (by reachability) : tout objet rfrenc par un objet persistant devient persistant. Ce mcanisme est rcursif : un objet qui est rendu persistant par rfrence rend persistant toutes les instances dont il a une rfrence. Cela participe la transparence de la persistance : seule la racine dune arborescence dobjets doit tre rendue explicitement persistante. On utilise pour cela la mthode suivante de la classe PersistentManager : void makePersistent(Object object)

2.2.Modification des donnes


Pour modifier des donnes de la base il suffit de modifier les instances JDO associes et de valider la transaction

2.3.Suppression des donnes


Pour supprimer des donnes persistantes, on utilise la mthode suivante de la classe PersistentManager : void deletePersistent(Object object) On peut aussi supprimer toute une collection ou un tableau dinstances persistantes avec les mthodes surcharges : void deletePersistentAll(Object[] objects) void deletePersistentAll(Collection array)

Si linstance que lon veut supprimer est rfrence par une autre instance persistante, il ne faut pas oublier denlever cette rfrence, sinon linstance redeviendra persistante par rfrence. En particulier, pour les relations 1 -N ou M-N, il ne faut pas oublier de retirer linsta nce que lon veut supprimer des collections qui correspondent ces relations..

3.Classes et interfaces de lAPI JDO

3.1.Packages de JDO
LAPI est compose de 2 packages : javax.jdo : les classes et interfaces utilises par les dveloppeurs, javax.jdo.spi : les classes et interfaces utilises par JDO pour son fonctionnement interne

3.2.Classes et interfaces principales


Interfaces : PersistentManager : interlocuteur principal de gestion de la persistance des instances, Transaction : permet de dmarrer, valider et invalider des transactions, Extent : collection de donnes, Query : permet slectionner les donnes rcupres dans la base via des flitres, PersistentManagerFactory : permet de rcuprer un PersistentManager, Classe : JDOHelper : classe utilitaire pour, par exemple, rcuprer une PersistentManagerFactory

3.3. Gestionnaire de persistance (GP)


Le gestionnaire de persistance est linterlocuteur principal du dveloppeur pour utiliser JDO. Il doit rpondre aux caractristiques suivantes : Une instance JDO est associe un seul GP, Un GP est responsable de la gestion de lidentit et de la persistance des instances JDO dont il a la charge, Il gre les transactions et les recherches dans la base, Un GP est une instance dune classe qui implmente l interface javax.jdo.PersistenceManager , Limplmentation de JDO fournit les GP, Un GP ne peut grer quune seule connexion une base un moment donn, Plusieurs GP peuvent tre utiliss si lapplication a besoin de plusieurs connexions/transactions en p arallle vers des sources de donnes (distinctes ou non).

3.4.Classes dexception JDO


Ce sont des sous-classes de RuntimeException (donc non contrles) places dans le paquetage javax.jdo. Il existe un grand nombre dexception, mais elles se rpartissents en 2 groupes de classes correspondant des sous-classes de : JDOFatalException : problmes impossibles traiter ; il faut arrter le traitement en cours, JDOCanRetryException : on peut essayer de relancer le traitement qui a lanc lexception, ou lancer un traitement alternatif.

4.Mta-donnes

4.1.Les mta-donnes
Utilises par lapplication et les outils JDO pendant lenrichissement des classes et lexcution de lapplication, elles donnent le point de vue des classes Java un point de vue objet sur les donnes persistantes ; par exemple, quels champs de la classe seront persistants (enregistrs dans la base) les relations entre les classes persistantes : 1 -1, 1-N, M-N. Il ny a cependant aucune information sur la base qui va contenir les donnes ; cest limplmentation

de JDO qui va utiliser dautres informations internes, ou ventuellement donnes dans dautres fichiers, pour faire le mapping (liaison) entre ce point de vue objet et le point de vue de la base de donnes (par exemple relationnel ). Des extensions permettent cependant de donner limplmentation JDO des indications sur la faon deffectuer ce mapping. Ces mta-donnes sont ranges dans un (ou plusieurs) fichier XML.

4.2.Exemple simple de mta -donnes


<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jdo SYSTEM "jdo.dtd"> <jdo> <package name="fr.labosun.jdoProject"> <class name="Chat"> <field name="nom"/> <field name="age"/> <field name="couleur"/> </package> </jdo>

4.3.Valeurs par dfaut pour les mta-donnes


Les valeurs par dfaut des mta -donnes sont dfinies par la spcification JDO et permettent de simplifier les mta-donnes. Il nest donc pas ncessaire de spcifier le tag field lorsque le type du champ correspond un type de persistance p ar defaut. <jdo> <package name="fr.labosun.jdoProject"> <class name="Chat"> </class> </package> </jdo>

4.4.Types persistants
Tous les champs ne peuvent pas tre dclars persistants ; ils doivent tre dun type accept par limplmentation JDO, la spcification JDO imposant que certains types soient accepts. Si un type nest pas persistant pour limplmentation utilise, on peut encore souvent sen sortir en utilisant des observateurs dvnements JDO.

4.5.Types persistants par dfaut


Les types persistants par dfaut sont : Types primitifs String BigDecimal et BigInteger Date Locale Classes PersistenceCapable Tableaux de types primitifs ou de type prcdemment cits Classes de collections (ArrayList,)

4.6.Types des champs persistants


Les champs persistants peuvent tre de type primitif les classes enveloppantes des types primitifs java.util.Locale java.math.BigDecimal et BigInteger

java.util.Date java.util.HashSet (optionnellement les autres classes collections) dune classe capable de persistance de la classe Object, mais limplmentation JDO peut restreindre les affectations ce champ en lanant une ClassCastException des interfaces collections Collection et Set (Map et List sont optionnels) de nimporte quelle interface, mais limplmentation JDO peut restreindre les affectations ce champ en lanant une ClassCastException

4.7.Valeurs par dfaut pour la cl primaire


Par dfaut lidentit des instances JDO est dfinie par la base (et non par lapplication). Dans les exemples prcdents, lidentit dune adresse est dfinie par la base.

4.8.Nom de classe
Si la classe appartient aux paquetages java.lang, java.util ou java.math, ou au package indiqu par le tag package dans lequel elle est indique, on peut ne donner que son n om terminal . Sinon, il faut donner le nom complet (prfix par le nom du paquetage). Les noms des classes internes sont crits sous la forme ClasseEnglobante$ClasseInterne

5.Dveloppement dune application JDO

5.1.Enrichissement des classes persist antes


Les classes des objets persistants doivent implmenter linterface javax.jdo.spi.PersistenceCapable . Le code li cette interface est automatiquement ajout par loutil JDO Enhancer (enrichissement des classes persistantes). Selon le produit JDO, ce t enrichissement peut tre effectu en modifiant le code source ou en modifiant directement le bytecode (sans doute le cas le plus frquent). Cependant, lenrichissement est portable entre diffrentes implmentations de JDO. Aucune permission spciale nes t requise pour travailler avec les champs privs des classes.

5.2.Interface PersistenceCapable
Elle est compose de quelques constantes et de mthodes qui permettent : de grer la persistance des instances, dinterroger une instance sur son tat au moment de lexcution. Toutes les mthodes ont des noms qui commencent par jdo ; ces mthodes sont utilises par JDO pour son fonctionnement interne.

5.3.Classpath pendant lexcution


Pour lenrichissement des classes persistantes, les classes de limplment ation de JDO (dans des fichiers jar le plus souvent) doivent tre dans le classpath ainsi que le(s) fichier(s) de mta -donnes. On doit, de plus, y ajouter le driver JDBC du logiciel utilis pour grer les objets persistants (un SGBD le plus souvent)

5.4.Processus de dveloppement
Le dveloppement standard dune application JDO sorganise comme suit : crire les classes sans se proccuper de la persistance, Reprer les classes correspondant aux objets persistants (classes capables de persistance ), crire les mta-donnes qui dcrivent le schma de la base de donnes et les informations pour rendre les objets persistants, Enrichir les classes persistantes avec les outils JDO, Utiliser les objets persistants pour crire et tester lapplication. Lintrt de JDO est que lon peut souvent compiler toutes les classes de lapplication avant mme davoir enrichi celles qui sont capables de persistance. En effet, les appels aux mthodes de

linterface PersistenceCapable sont effectus par limplmentation de JD O ; elles ne sont donc pas crites dans les classes de lapplication et ne provoquent donc pas derreurs de compilation.

5.5.Outils de dveloppement
Les implmentations de JDO fournissent des outils pour : enrichir les classes persistantes (indispensable) , gnrer les ordres SQL pour crer le schma de la base de donnes. partir des mta donnes (optionnel), gnrer les mta-donnes partir dune base de donnes existante (optionnel).

6.Exemple simple de code


6.1.Le logiciel ncessaire
Une implmentation de JDO Un SGBD Un driver JDBC pour ce SGBD Pour ce cours, on utilisera les logiciels gratuits en open source suivants : limplmentation de JDO LiDO (http://www.libelis.com) le SGBD MySQL (http://www.mysql.org) le driver JDBC MM.MySQL (http://mmm ysql.sourceforge.net)

6.1.1.LiDO Community Edition


Cette version est gratuite et rserve aux utilisations non commerciales et comporte une limitation : pas doutil pour travailler avec une base de donnes existante. Les SGBD commerciaux (Oracle en particulier) ne sont pas supports. La version commerciale de LiDO contient toutes ces fonctionnalits. Les dveloppeurs LiDO sont trs ractifs et cooprants avec la communaut des dveloppeurs

6.1.2.Problme ventuel avec les IDE


La plupart des IDEs compilent a utomatiquement les classes en arrire -plan. La version enrichie des .class peut donc tre crase par une version non enrichie obtenue automatiquement partir du fichier source. Pour viter ce problme, il faut une version de lIDE qui prendront en co mpte JDO

6.2.Le code
On doit importer le paquetage javax.jdo qui contient les classes distribues par Sun. Le plus souvent JDO napparat que par lintermdiaire du gestionnaire de persistance

6.2.1.Classe de base
fr.labosun.jdoProject; Chat { String nom; String couleur; String age; Chat(String nom, String couleur, String age){ .nom = nom; .couleur = couleur; .age = age; } String getNom() { nom; } setNom(String nom) { .nom = nom; }

... String toString(){ nom+" - "+couleur+" "+age; } }

6.2.2.Enrichissement de la classe
On utilise loutil pour enrichir la classe Chat ; dans limplmentation de JDO LiDO, cest la classe Java Enhance qui fait office de cet outil. On doit lui passer : une classe Java enrichir des mta-donnes qui dcrivent les classes persistantes

6.2.3.Mta-donnes
<jdo> <package name="fr.labosun.jdoProject"> <class name="Chat"> <field name="nom"/> <field name="couleur"/> <field name="age"/> </class> </package> </jdo>

6.2.4.Enrichissement de la classe : excution avec LiDO


Les fichiers jar du rpertoire lib de LiDO et le rpertoire bin de LiDO doivent tre dans le classpath. On lance lexcution de la classe LiDO : set LIDO_HOME=C:\Program Files\LiDo java cp "%LIDO_HOME%\lib\lido-rt.jar;..." metadata

6.2.5.Tester les classes persistantes


Il reste crer la base de donnes qui va contenir les objets persistants. On utilisera ici le SGBD MySQL. On peut ensuite crire du code qui va utiliser les classes persistantes enrichies (ici la classe Chat.class)
1.

Outil pour construire le schma de la base de donnes

Les implmentations de JDO offrent dautres outils que lenrichisseur de classes. Un des outils permet de gnrer le code pour construire la base de donnes qui va contenir les objets persistants. Pour LiDO la classe DefineSchema a cette fonction. Le paramtre -sql permet denregistrer dans un fichier les ordres SQL qui vont crer la base, sans les faire excute r (utile pour information et en cas de problme)
2.

Construire le schma de la base de donnes avec LiDO

On doit indiquer le driver JDBC, lURL JDBC de la base et le fichier qui contient les mta donnes : Le classpath doit contenir les classes enrichies de lapplication, les fichiers jar de limplmentation de JDO et le driver JDBC java com.libelis.lido.ds.jdbc.DefineSchema :

driver : com.mysql.jdbc.Driver database : jdbc:mysql://localhost/chats metadata : metadata.jdo set LIDO_HOME=C:\Program Files\LiDo java -cp "%LIDO_HOME%\lib\lido-rt.jar;..."

6.2.6.Ajouter un Chat la base

javax.jdo.Transaction; Test1 { String DBURL = "jdbc:mysql: //localhost/chats"; String DBDRIVER = "com.mysql.jdbc.Driver";

6.2.7.Fabrique de gestionnair e de persistance


Exception { // Crer une fabrique de gestionnaire de persistance PersistenceManagerFactory pmf = (PersistenceManagerFactory) Class .forName("com.libelis.lido.PersistenceManagerFactory") .newInstance();

6.2.8.Dmarrer une transaction


pmf.setConnectionURL(DBURL); pmf.setConnectionDriverName(DBDRIVER); // Rcuprer le gestionnaire de persistance PersistenceManager pm = pmf.getPersistenceManager(); // Dmarrer une transaction Transaction t = pm.curr entTransaction(); t.begin();

6.2.9.Rendre un Chat persistant


// Cre un nouveau Chat... Chat chat = Chat("Felix", "noir", "5"); // ... et le rend persistant pm.makePersistent(chat);

6.2.10.Enregistrer le Chat dans la base


// Commit la transaction. // Le Chat est enregistre automatiquement dans la base ! t.commit(); // Fermeture du gestionnaire de persistance pm.close(); } }

6.2.11.Excuter Test1
Le fichier metadata.jdo est utilis pendant lexcution des classes persis tantes. Avec LiDO, on peut indiquer son emplacement avec la proprit Java jdo.metadata : java Djdo.metadata=<filepath> -classpath ... fr.labosun.jdoProject.Test1

7.Concepts plus avancs de JDO

7.1.Hritage et classes persistantes

7.1.1.Pr requis
Si on a une hirarchie dhritage, une classe peut tre persistante ou non, indpendamment des autres classes de larborescence (classes filles ou mres). Pour cela, il faut que : Toutes les classes persistantes de larborescence doivent avoir la mme cl pr imaire (gre par la base ou par lapplication), donne dans la classe la plus haute hirarchiquement, Tous les champs persistants le restent dans les classes filles persistantes, Toutes les classes doivent avoir un constructeur sans paramtre.

7.1.2.Mta-donnes pour les classes filles persistantes


On peut indiquer la classe mre persistante dune classe persistante par un attribut du tag class : persistence-capable-super > Exemple : <class name="Salarie" "/> <field name="salaire"/> </class> On ne doit pas dclarer les champs persistants hrits, ni la cl primaire. On peut aussi ne pas indiquer cet hritage dans le fichier de metadata si on ne veut pas que JDO tienne compte dune classe mre persistante.

7.1.3.Exemple 3. Mta-donnes : classe Personne


<class name="Personne"> <field name="adresse"/> <field name="prenom"/> <field name="nom"/> </class>

4.

Mta-donnes : classe Salarie

<class name="Salarie" persistence-capable-super <field name="prime"/> <field name="salaire"/> </class>

5.

Classe Personne

fr.labosun.jdoProject; Personne { String nom, prenom, adresse; Personne (String nom, String prenom, String adresse) { .nom = nom; .prenom = prenom; .adresse = adresse;

} String getNom() { nom; } setNom(String nom) { .nom = nom; } //... (get/set) }

6.

Classe Salarie

fr.labosun.jdoProject; Personne { double prime; double salaire; Salarie(double prime, double salaire, String nom, String prenom, String a dresse) { (nom, prenom, adresse); .prime = prime; .salaire = salaire; } String getPrime() { prime; } setPrime(double d) { prime = d; } //... (get/set) }

7.3.Relations entre classes


Par le code Java et les mta -donnes on peut dcrire des relations entre les classes persistantes. Ces relations pourront permettre de naviguer d'une classe l'autre lors des requtes crites en JDOQL (voir section 8).

7.3.1.Relations 1-1 entre classes persistantes


Inclure dans chacune des classes une variable du type de l'autre classe. <class name="Salarie"> <field name="poste"/></class> <<SPAN class="sourceKeyword">class name="Poste"> <field name="salarie"/></class> On peut ne pas faire cette inclusion dans les 2 sens si on interdit la navigation dans un des sens.

7.3.2.Relations 1-n entre classes persistantes


Inclure dans la classe matresse une variable contenant une collection d'instances de l'autre classe : <class name="Societe"> <field name="salaries"> </class> </field>

Et dans l'autre classe une variable du type de l'autre classe : <class name="Salarie"> <field name="societe"/> ...</class> On peut ne pas faire cette inclusion si on veut interdire la navigation vers la classe matresse .

7.3.3.Relations m-n entre classes persistantes


Inclure dans chacune des classes une variable contenant une collection d'instances de l'autre classe. <class name="Projet"> <field name="salaries"> <collection element type="fr.labosun.jdoProject.Salarie"/> </field> </class> <class name="Salarie"> <field name="projets"> <collection element type="fr.labosun.jdoProject.Projet"/> </field> </class> On peut ne pas faire une des 2 inclusions si on veut interdire la navigation dans un des sens.

7.3.4.Exemple de relation 1-1 et 1-n 12. Mta-donnes : classe Zoo

<class name="Zoo"> <field name="singes"> <collection element -type="fr.labosun.jdoProject.Singe"/> </field> <field name="nom"/> <field name="directeur"/> </class>
13.

Mta-donnes : classe Singe

<class name="Singe"> <field name="nom"/> <field name="age"/> <field name="couleur"/> <field name="zoo"/> </class>

14.

Mta-donnes : classe Directeur

<class name="Directeur" <field name="nom"/> <field name="salaire"/> <field name="zoo"/> </class>

15.

Classe Zoo

fr.labosun.jdoProject;

java.util.Collection; Zoo { String nom; Collection singes; Directeur directeur; Zoo(String nom) { singes = ArrayList(); .nom = nom; } addSinge(Singe singe) { singes.add(singe); } removeSinges(Singe singe) { singes.remove(singe); } Collection getSinges() { singes; } setSinges(Collection singes) { .singes = singes; } //... (get/set) }

16.
fr.labosun.jdoProject;

Classe Singe

Singe { String nom, age, couleur; Zoo zoo; Singe(String nom, String age, String couleur) { .nom = nom; .age = age; .couleur = couleur; } String getNom() { nom; } setNom(String nom) { .nom = nom; } //... (get/set) }

17.
fr.labosun.jdoProject; Directeur{ String nom; salaire; Zoo zoo;

Classe Directeur

salaire, Zoo zoo) { .nom = nom; .salaire = salaire; .zoo = zoo; } String getNom() { nom; } setNom(String nom) { nom = nom; } //... (get/set) }

8.Le Langage dinterrogation JDOQL (JDO Query Language)

8.1.Introduction
2 parties : l'API pour faire des requtes : des mthodes de la classe PersistenceManager, le langage d'interrogation lui-mme. JDOQL permet de retrouver, modifie r et supprimer des donnes gres par un gestionnaire de persistance.

8.2.Interface Extent
JDOQL utilise intensivement l'interface javax.jdo.Extent. Une instance d'une classe qui implmente Extent est une sorte de collection d'instances JDO qui reprsente des donnes de la base ; les donnes de la base reprsentes par les instances contenues dans l'Extent ne sont vraiment rcupres qu' la demande, par l'itrateur qui le parcourt.

8.2.1.Obtenir un Extent
On utilise la mthode getExtent de la classe PersistenceManager laquelle on doit passer en paramtres pour rcuprer une instance d Extent : la classe des instances persistantes contenues dans l' Extent (preciser le package complet si besoin), dire si on veut inclure les instances des sous -classes de cette classe.

8.2.2.Exemple simple de recherche


// Retrouve tous les singes Extent extent = pm.getExtent(Singe.); Iterator i = extent.iterator(); (i.hasNext()) { Singe singe = (Singe) i.next(); System.out.println("Singe : "+singe.getNom()+", "+singe .getAge()); } extent.closeAll();

8.3.Recherche d'information
La recherche dinformation se fait avec la classe javax.jdo.Query qui permet de rcuprer des instances persistantes enregistres dans la base. Dans la version actuelle de JDO, une recherche ne donne pas des valeurs de champs mais des instances entires.

8.3.1.Obtenir un Query
Pour obtenir une instance de Query, on utilise la mthode newQuery de la classe PersistenceManager (qui est la fabrique de Query). Il existe un grand nombre de mthodes Query surcharges, mais un Query a besoin de : la classe des instances que l'on veut obtenir, ou d'une collection (ou d'un extent) dans laquelle chercher (ils sont appels les candidats ), et optionnellement d'un filtre pour slectionner les instances (cf. 8.4).

Query query = pm.newQuery(extent, "zoo.nom == z"); Query query = pm.newQuery(Singe., "zoo.nom == z");

8.3.2.Classe Query
La cration dun Query nest pas fixe ds lors quon la instanci ; on peut le paramtrer grce aux mthodes suivantes : On peut modifier un Query avec les mthodes setClass(), setFilter(), setCandidate() On peut fixer un ordre par setOrdering() (syntaxe proche de SQL : salaire descending, nom) On peut compiler le Query (mthode compile()), ce qui permet de vrifier les l ments du Query et de donner une chance limplantation JDO doptimiser le Query pour plusieurs utilisations futures.

8.3.3.Excution du Query et paramtres


Le Query est lanc par la commande execute. Les recherches sont souvent paramtrables. Par exemple , un paramtre peut indiquer le numro de Scurit Sociale de la Personne dont on veut les informations ; execute est surcharge pour passer jusqu 3 paramtres au Query. Au-del de 3, il faut choisir comment passer les paramtres : par tableau (executeWithArray) ou par Map (executeWithMap).

8.3.4.Dclaration des paramtres


Les paramtres utiliss dans un query doivent tre dclars. La syntaxe est proche de celle de Java ( , est le sparateur). Par exemple : query.declareParameters("String nomSinge, S tring ageSinge");

8.3.5.Dclaration des variables


Les variables utilises dans un query doivent tre dclares. La syntaxe est proche de celle de Java ( , est le sparateur). Par exemple : query.declareVariables("Singe singe");

8.3.6.Importation de classes
On peut aussi avoir besoin d'importer des classes de dclaration des paramtres ou des variables (dcrites plus loin) pour enlever une ambigut. La syntaxe est celle de Java ( ; est le sparateur) : query.declareImports(" import java.util.Date; import fr.labosun.AutreCls");

8.3.7.Rsultat de lexcution du Query


La mthode execute renvoie un Object, que lon doit caster en Collection. Collection qryResults = (Collection) query.execute();

8.3.8.Analogie d'un Query avec une mthode


On peut considrer un Query comme une mthode place dans la classe des instances que l'on recherche : Les paramtres du Query correspondent aux paramtres de la mthode, Les variables correspondent aux variables locales de la mthode, Les imports correspondent aux importations de classes ncessaires l'excution de la mthode.

8.3.9.Exemple :
Extent extSinges = pm.getExtent(Singe. class, ); Query q = pm.newQuery(extSinges, "zoo.nom == z"); q.declareParameters("String z"); Collection singes = (Collection) q.execute("Zoo de Vincenne");

8.2.Interface Extent
JDOQL utilise intensivement l'interface javax.jdo.Extent. Une instance d'une classe qui implmente Extent est une sorte de collection d'instances JDO qui reprsente des donnes de la base ; les donnes de la base reprsentes par les instances contenues dans l'Extent ne sont vraiment rcupres qu' la demande, par l'itrateur qui le parcourt.

8.2.1.Obtenir un Extent
On utilise la mthode getExtent de la classe PersistenceManager laquelle on doit passer en paramtres pour rcuprer une instance d Extent : la classe des instances persistantes contenues dans l' Extent (preciser le package complet si besoin), dire si on veut inclure les instances des sous -classes de cette classe.

8.2.2.Exemple simple de re cherche


// Retrouve tous les singes Extent extent = pm.getExtent(Singe.); Iterator i = extent.iterator(); (i.hasNext()) { Singe singe = (Singe) i.next(); System.out.println("Singe : "+singe.getNom()+", "+singe.getAge()); } extent.closeAll();

8.3.Recherche d'information
La recherche dinformation se fait avec la classe javax.jdo.Query qui permet de rcuprer des instances persistantes enregistres dans la base. Dans la version actuelle de JDO, une recherche ne donne pas des valeurs de champs m ais des instances entires.

8.3.1.Obtenir un Query
Pour obtenir une instance de Query, on utilise la mthode newQuery de la classe PersistenceManager (qui est la fabrique de Query). Il existe un grand nombre de mthodes Query surcharges, mais un Query a besoin de : la classe des instances que l'on veut obtenir, ou d'une collection (ou d'un extent) dans laquelle chercher (ils sont appels les candidats ), et optionnellement d'un filtre pour slectionner les instances (cf. 8.4).

Query query = pm.newQu ery(extent, "zoo.nom == z"); Query query = pm.newQuery(Singe., "zoo.nom == z");

8.3.2.Classe Query
La cration dun Query nest pas fixe ds lors quon la instanci ; on peut le paramtrer grce aux mthodes suivantes : On peut modifier un Query avec les mthodes setClass(), setFilter(), setCandidate() On peut fixer un ordre par setOrdering() (syntaxe proche de SQL : salaire descending, nom) On peut compiler le Query (mthode compile()), ce qui permet de vrifier les lments du Query et de donner une chance limplantation JDO doptimiser le Query pour plusieurs utilisations futures.

8.3.3.Excution du Query et paramtres


Le Query est lanc par la commande execute. Les recherches sont souvent paramtrables. Par exemple, un paramtre peut indiquer le num ro de Scurit Sociale de la Personne dont on veut les informations ; execute est surcharge pour passer jusqu 3 paramtres au Query. Au-del de 3, il faut choisir comment passer les paramtres : par tableau (executeWithArray) ou par Map (executeWithMap).

8.3.4.Dclaration des paramtres


Les paramtres utiliss dans un query doivent tre dclars. La syntaxe est proche de celle de Java ( , est le sparateur). Par exemple : query.declareParameters("String nomSinge, String ageSinge");

8.3.5.Dclaration des variables


Les variables utilises dans un query doivent tre dclares. La syntaxe est proche de celle de Java ( , est le sparateur). Par exemple : query.declareVariables("Singe singe");

8.3.6.Importation de classes
On peut aussi avoir besoin d'importer des classes de dclaration des paramtres ou des variables (dcrites plus loin) pour enlever une ambigut. La syntaxe est celle de Java ( ; est le sparateur) : query.declareImports(" import java.util.Date; import fr.labosun.AutreCls");

8.3.7.Rsultat de lexcution du Query


La mthode execute renvoie un Object, que lon doit caster en Collection. Collection qryResults = (Collection) query.execute();

8.3.8.Analogie d'un Query avec une mthode


On peut considrer un Query comme une mthode place dans la classe des instances que l'on recherche : Les paramtres du Query correspondent aux paramtres de la mthode, Les variables correspondent aux variables locales de la mthode, Les imports correspondent aux importations de classes ncessaires l'excution de la mthode.

8.3.9.Exemple :
Extent extSinges = pm.getExtent(Singe. class, ); Query q = pm.newQuery(extSinges, "zoo.nom == z"); q.declareParameters("String z"); Collection singes = (Collection) q.execute("Zoo de Vincenne");

8.4.Filtres
Lors de la cration du Query, on peut filtr ds celle-ci les rsultats qui seront retourns grce a des filtres. La condition de slection des filtres peut tre complexe et peut comporter des && , || , ! comme en Java. Elle peut aussi utiliser les noms des champs de la classe des instances recherches, ainsi que des mthodes. Les seules mthodes autorises dans les filtres sont : Des mthodes sur les String, Des mthodes sur les Collection.

8.4.1.Mthodes sur les String


On peut selectionner les rsultats en analysant les String retournes grce aux mthodes suivantes : startsWith() String filter = "(singe.age > 10) && (singe.nom.startsWith( \"A\"))" endsWith() String filter = "(singe.age > 10) && (singe.nom.endsWith( \".\"))"

8.4.2.Mthodes sur les Collection


On peut selectionner les rsultats en testant directement sur la Collection retourne grce aux mthodes suivantes : contains() Cette mthode doit tre utilise la gauche de loprateur & (ou &&). Son but est dassocier une variable aux lments de la Collection ; cette variable peut tre alors utilise dans lexpression place droite de loprateur &. Si le champ de la classe dont on cherche les instances correspond une Collection d'une autre classe persistante et correspo nd une relation dclare dans les mta -donnes, on peut naviguer dans la Collection. Pour cela, il faut associer une variable aux lments de la Collection et donner

une condition qui devra tre remplie par au moins un lment de celle -ci pour que la condition soit vraie. query.declareVariables("Singe singe"); String filter = "singes.contains(singe) & singe.age > 5" Ca peut s'interprter comme la variable singe est contenue dans la Collection singes et elle vrifie singe.age > 5 . isEmpty() (renvoie true si la collection est vide) String filter = "singes.isEmpty()"

8.4.3.Remarque importante
Les noms utiliss dans les filtres sont les noms des classes Java et des variables persistantes. Il ne faut pas utiliser les noms des tables (ou autres) dans l esquelles les donnes vont tre enregistres. Le principe de JDO est que lon travaille sur des objets sans pour autant connatre les tables relationnelles ou autres supports de donnes.

8.4.4.Exemple
Extent extent = pm.getExtent(Zoo.); String filter = "directeur.salaire > min && directeur.nom.startsWith( \"letter\")"; Query qry = pm.newQuery(extent, filter); qry.declareParameters("String min, String letter"); Collection zoos = (Collection) qry.execute("1200","A"); Iterator it = zoos.iterator (); (it.hasNext()) { Zoo zoo = (Zoo) it.next(); System.out.println("Zoo : "+zoo.getNom()); } Cet exemple permet de rcuprer et dafficher toutes les instances persistantes du Zoo dont le directeur a un salaire de plus de 1200 et dont le nom commen ce par A.

8.5.Complments sur PersistenceManager


Le gestionnaire de persistance fourni aussi les mthodes suivantes : refresh(Object instanceJDO) , refreshAll(Object[] instancesJDO) , refreshAll(Collection instancesJDO) , refresh(). Celles-ci permettent de rafrachir ltat des instances JDO pour quelles reprsentent les valeurs actuelles de la base. Elles peuvent tre utilises dans une transaction optimiste pour avoir plus de chance de succs de la transaction au moment du commit. Il fourni aussi les mthodes : retrieve(Object instanceJDO) , retrieveAll(Object[] instancesJDO) , retrieveAll(Collection instancesJDO) . Celles-ci permettent dinformer le gestionnaire de persistance que lapplication a lintention dutiliser ces instances JDO. Il aura ainsi lo ccasion doptimiser ces rcuprations.

9.Etats des instances JDO

9.1.Dfinition
Le modle objet des donnes manipules par JDO (les instances JDO) contient 2 types dinstances : FCO (First Class Object) : instance JDO qui ont une identit JDO, SCO (Second Class Object) : elle na pas didentit JDO par elle -mme ; elle correspond des donnes qui sont enregistres comme une partie des donnes dun FCO.

9.2.FCO et SCO
Les types qui correspondent aux interfaces qui ne sont pas des collections doivent tre implments avec des FCO. Tous les autres types peuvent tre implments avec des FCO et des SCO La spcification indique que les applications JDO ne doivent pas dpendre du fait que ces types sont implments par des FCO et des SCO Mais, il nest pas vident de savoir comment faire quand on lit cette spcification

Vous aimerez peut-être aussi