Utilisation de JDO dans une application web (JPox/Tomcat)Date de publication : 20/05/2005 , Date de mise a jour : 20/05/2005
Cet article fait suite au "Tutorial sur l'utilisation de JDO sur une base de donnée relationnelle".
Il se propose de décrire l'intégration d'un modèle métier persisté par le driver JDO JPox au sein d'un serveur d'application Tomcat 5.x. 1. Introduction 2. Installation des composants 2.1. MySQL 2.1. JPox 2.2. Tomcat 5.x 3. Déploiement 3.1. Installation de l'application Discothèque 3.2. Paramétrage de la source de données 3.3. Création des données 3.4. Vérification des données 3.5. Requêtes 4. Creusons ! 4.1. Conception de "Discothèque" 4.2. L'accès au persistence manager 4.3. Détachement des objets 4.3.1. La requête 4.3.2. Définition du plan de récupération (Fetch Plan) 5. Conclusion 5.1. Crédits et License 1. Introduction
Ce tutoriel va vous montrer comment intéger un modèle métier persisté par le driver JDO JPox au sein d'un serveur d'application Tomcat 5.x.
Pour une explication complète des concepts JDO reportez vous à l'article Tutorial sur l'utilisation de JDO sur une base de donnée relationnelle.
Ce tutorial suppose que le lecteur est familié avec le serveur d'application Tomcat 5.x et possède des connaissances sur les mécanismes de persistance JDO.
La première partie de l'article est consacrée à l'installation des produits. Ensuite il enchaine sur le déploiement d'un exemple et termine sur les quelques points spécifiques à cette intégration.
2. Installation des composantsDans notre tutorial nous allons faire persister nos classes Java dans une base de données MySQL en utilisant le driver opensource JPox s'exécutant dans le container Web Apache/Tomcat. 2.1. MySQL2.1. JPox2.2. Tomcat 5.x
Tomcat est une implémentation open source d'un container web J2EE. Il permet d'écrire des applications web dynamiques en utilisant les technologies Servlet et JSP.
Pour télécharger une version, rendez vous ICI. Il existe pour les environnements de type Microsoft Windows,
un programme d'installation automatique. Pour les autres environnements, il faut télécharger une version archive type .tar.gz. Pour plus d'informations sur la technologie Servlet et Tomcat, reportez vous à l'article Créer et déployer un premier servlet avec TomCat publié par LFE. 3. Déploiement
Cette partie va détailler comment déployer un exemple d'un modèle géré en persistance par JDO dans le container web Tomcat. Vous aurez besoin pour ceci de télécharger l'archive (WAR) et le fichier de paramétrage.
3.1. Installation de l'application Discothèque
Cette application est la suite du modèle Complexe présenté dans la première partie.
Le modèle comporte des notions d'artistes, de personnes, de groupes, d'albums, de pistes. Les services de notre application discothèque vont nous permettre de créer des instances du modèle, de vérifier que l'on a bien tout persisté et d'effectuer des requêtes.
Démarrez le serveur d'application tomcat et ouvrez la page d'administration http://localhost:8080/manager/html
Vous devez obtenir un écran comme celui-ci:
Cliquez sur le bouton "Parcourir" de la section "WAR File to Deploy" et Sélectionner le fichier discotheque.war présent dans le fichier tutoriel_jpox_tomcat.zip. Cliquez sur le bouton "Deploy"
L'application est déployée. Si vous cliquez sur le lien /discotheque vous devez arriver sur une page vous proposant les 3 services de l'applications.
Ne cliquez pas tout de suite sur les liens, il reste à configurer la base de données.
3.2. Paramétrage de la source de données
Avant d'exécuter notre application, il faut définir la source de données utilisée par le driver JDO. Cette source de données sera gérée par le web container Tomcat. Si vous ouvrez le fichier discotheque.xml, vous voyez:
Il vous faut modifier les paramètres de la Datasource (driverClassName, url, username et password) en adéquation avec votre configuration mysql.
Ensuite, copier le fichier discotheque.xml dans le répertoire %TOMCAT_HOME%/conf/Catalina/localhost et recharger l'application avec l'aide de l'application Manager de Tomcat.
3.3. Création des données
L'application est prête à être utilisée. Lancer votre navigateur sur l'url http://localhost:8080/discotheque/. Cliquer sur "Création des Données: CreateData".
Ce service va peupler la base de données. Les données insérées sont les mêmes que l'exemple 4.3. Création de données.
Si tout se passe correctement l'application vous répond:
Creation des données..................ok 3.4. Vérification des données
Pour vérifier que les données sont correctement persistées, nous allons compter le nombre d'instances insérées.
Lancer votre navigateur sur l'url http://localhost:8080/discotheque/. Cliquer sur "Vérification des données: CheckData".
Le code de contrôle est le même que l'exemple 4.4.1. Vérification du nombre d'instance.
Si tout se passe correctement l'application vous répond:
3 albums de Pink Floyd, 1 de Television et le best of d'Enio Morricone Nombre d'instance de class org.moussaud.data.Album = 5 Pink Floy et Television Nombre d'instance de class org.moussaud.data.Group = 2 Enion Moricone, les 5 membres de PF Nombre d'instance de class org.moussaud.data.Person = 6 Groupe + Person Nombre d'instance de class org.moussaud.data.Artist = 8 Tracks Nombre d'instance de class org.moussaud.data.Track = 38 Genre: rock, blues Nombre d'instance de class org.moussaud.data.Genre = 2 3.5. Requêtes
Nous allons maintenant demander à l'application Discotheque de nous ramener l'ensemble des albums avec leur genre; une fois non trié, une fois trié. Lancer votre navigateur sur l'url http://localhost:8080/discotheque/. Cliquez sur "Requete sur les données: SortData".
Ce service va effectuer une requête JDO sans rien préciser. Ensuite il réitère la même requête en demandant un tri au niveau du nom. Le code de contrôle est le même que l'exemple 4.4.2. Les Tris.
Si tout se passe correctement l'application vous répond:
Liste des Albums (non triés)
* The Wall - rock
* Dark Side Of The Moon - rock
* Wish you Were Here - rock
* Marquee Moon - rock
* Compilation - Blues
Liste des Albums (triés)
* Compilation - Blues
* Dark Side Of The Moon - rock
* Marquee Moon - rock
* The Wall - rock
* Wish you Were Here - rock
Voici donc une application utilisant JDO (Driver JPox) avec le web container J2EE Tomcat. La section suivante va détailler quelques points particuliers.
4. Creusons !
Dans cette partie nous allons décrire l'exemple - discotheque.war - et s'attarder sur deux points en particulier:
4.1. Conception de "Discothèque"
L'application Discotheque est articulée pour les 3 services sur un modèle classique:
![]() Conception
Le navigateur envoie la requête sur une Servlet qui s'appuie sur une couche service pour répondre à sa requête (Classe DiscothequeManager). Cette couche utilise les API JDO pour créer et manipuler le modèle et répondre au service. Les données récupérées, la couche présentation (ui) appelle une JSP pour l'affichage.
Le motif de conception est le MVC, Modèle Vue Contrôleur, sans Struts !
4.2. L'accès au persistence manager
La classe DiscothequeManager est un mélange entre une classe service et une classe DAO. En effet, dans notre exemple simple, il n'est pas nécessaire de séparer les 2 couches. Dès qu'une méthode a besoin d'accéder à JDO, elle a besoin d'une instance de la classe PersistenceManager. Cette classe va lui offrir de pouvoir faire persister des objets, les détruire, faire des requêtes. L'application s'exécute dans un environnement serveur, il n'est pas concevable, à chaque requête:
En particulier l'étape #2 est très consommatrice de ressources: lecture de la configuration JDO, initialisation des paramètres internes, connexion à la base de données,....
Donc la classe DiscothequeManager utilise une classe PMHelper qui va lui fournir une instance de PersistenceManager qui correspond au contexte d'exécution (Méthode a()).Cette méthode associe une instance de PersistenceManager au Thread courant via l'objet magique ThreadLocal. Si le thread courant n'est pas associé avec une instance, il en instancie une nouvelle et lui associe. Sinon, le thread est déja associé à un PersistenceManager, il lui retourne celle existant. Ce pattern permet à toute méthode d'obtenir une instance de PersistenceManager sans nécessiter de la passer de méthode en méthode.
L'objet ThreadLocal nous assure qu'il n'y aura de collisions en cas d'exécutions parallèlse: chaque requête est associée à un thread géré par le serveur d'application. Par contre, il est absolument nécessaire de faire un fermer l'association (PMHelper.closePM()) en fin de service.
Ce pattern est couramment utilisé dans les frameworks, et en particulier les frameworks de persistance.
Exemple: avec Hibernate 2.x, Thread Local Session
4.3. Détachement des objets
L'un des problèmes que l'on rencontre quand on interagit avec un framework de persistance ou un ResultSet JDBC, c'est que les objets retournés sont en lien plus ou moins direct avec la source de données. Ceci est très fâcheux quand on doit les transmettre à une page JSP ou à des méthodes métiers en dehors de la transaction courante.
Généralement la solution envisagée est de créer une famille de Java Bean, ressemblant généralement au modèle, pour accueillir les données. Ce pattern est connu sous le nom de DTO (Data Transfert Object) ou VO (Value Object). Avec schéma, les applications se retrouvent avec une quantité importante d'objets et de services qui font le transfert entre le modèle DTO et le modèle persisté. La valeur ajoutée n'est pas énorme mais le temps de développement, de maintenance et d'exécution augmente !
Les frameworks de persistance tels que JDO ou Hibernate ont bien compris ce besoin (ou cette nécessité) de pouvoir manipuler ces objets de manière déconnectée de la base de données. En JDO, ces méthodes existent: PersistenceManager.attach() et PersistenceManager.detach().
Dans notre exemple, nous allons voir comment utiliser détacher des instances pour transmettre la liste des albums et des genres directement à la JSP pour affichage.
4.3.1. La requête
Si on regarde la requête faite pour trier les albums on a le code suivant:
Si on compare au code utilisé dans la version autonome du sample,
On remarque deux lignes supplémentaires
4.3.2. Définition du plan de récupération (Fetch Plan)
Si on regarde de près le fichier package.jdo, on voit pour la classe Ablum, la définition suivante:
En plus de la désormais classique définition des champs (field) on voit maintenant apparaître la définition des fetch groups. Ces fetch groups définissent explicitement quelles instances de classes doivent être récupérées (chargées) en même temps que l'instance.
Cette récupération étendue peut être nécessaire comme notre exemple pour transmettre des objets mais aussi pour indiquer au driver JDO que l'on avoir besoins de ces instances et qu'il doit les récupérer en une seule fois (optimisation possible au niveau de l'implémentation). Exemple: si pour un traitement, on a besoin de parcourir l'ensemble des pistes d'un album pour calculer la durée total de l'Album, autant définir un fech group sur les instances de type Track.
Il est possible de définir autant de fetch groups que l'on souhaite pour une classe donnée. On peut voir ces fetch groups comme des Cas d'Utilisation. Exemple:
5. Conclusion
Cet article vous a montré comment l'utilisation d'un composant de persistance tel que JDO pouvait s'intégrer facilement au sein d'un serveur Tomcat, en apportant performance et simplicité dans la persistance vos modèles métiers.
Une étape supplémentaire pour une conception complète serait d'y ajouter l'utilisation du framework . Spring permet de prendre en charge
Source complet de l'application est disponible en Téléchargement (WorkSpace Eclipse 3.1 avec WTP)
5.1. Crédits et License
Ce tutorial est écrit par Benoit Moussaud, Consultant Sénior en Architecture J2EE chez Xebia
Pour un contact ou des précisions, n'hésitez pas à m'écrire: bmoussaud@xebia.fr Copyrights Benoit Moussaud 2005 |
Copyright © 2005 Benoit Moussaud. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Cette page est déposée.
Copyright © 2000-2012 - www.developpez.com