Persistance des objets

Persistance des objets

Dans l’architecture  en  couches  des  applications  distribuées, la  couche  de  persistance  permet  de  faire le lien  avec la  sauvegarde physique des données. Nous avons des objets qui représentent des entités avec des états : ● une personne avec son nom, son âge, sa date de naissance… ; ● un compte bancaire avec son numéro, son solde… ; ● une adresse ; ● etc. Ces objets ont des états en mémoire et si l’application est arrêtée, cet état n’est pas sauvegardé. Le développeur doit  donc se soucier du maintien de l’état dans une base de données : la persistance. Le nec plus ultra pour le développeur  serait  qu’il  n’ait  pas  à  se  soucier  des  mécanismes  sous­jacents  qui  permettent  aux  objets  d’être  « persistés ».  Ceci  arrivera peut­être un jour… Cette sauvegarde est principalement effectuée dans une base de données, en général, relationnelle : Oracle, MySql,  PosgreSQL, HSQLDB. Elle peut aussi être effectuée par sérialisation utilisation de fichiers, de XML, etc. Cette couche va encapsuler les mécanismes qui auront la responsabilité de sauvegarder, modifier ou restaurer l’état de  certains des objets métiers de l’application. Il ne doit pas y avoir de requêtes SQL, ou autres, qui parsèment l’ensemble du code des autres couches applicatives.  Idéalement, le développeur ne devrait pas avoir à se soucier des mécanismes sous­jacents utilisés pour permettre la  persistance  de  ses  objets.  Cette  couche  doit  aussi  permettre  de  garder  une  certaine  indépendance  vis­à­vis  de  l’architecture de la base de données utilisée. Les couches de persistance s’appuient sur l’API JDBC. De très nombreuses implémentations de cette couche peuvent être envisagées : ● codage de la couche par le développeur en utilisant l’API JDBC ; ● utilisation du framework Hibernate qui est inclus dans la distribution JBoss ; ● utilisation des EJB entités ; ● utilisation d’autres frameworks…

Codage du pattern DAO

Si le codage de la couche est effectué par le développeur, celui­ci mettra certainement en pratique le design pattern  DAO (Data Acces Object). Ce design pattern de conception montre comment encapsuler tous les accès aux sources de  données.  En  général,  à  chaque  objet  métier  est  associé  un  objet  DAO  qui  contient  le  code  SQL  nécessaire  à  la  sauvegarde, modification, suppression en base de données. Les sources présentés ici, sont issues du projet « Chap4 ­ JDBC ». Par exemple, une classe métier Ville est associée à  une  classe  VilleDAO  qui  contiendra les méthodes  permettant l’ajout, les  recherches en base de données, etc.  Les  méthodes de  cette  classe DAO  renvoient un objet, ou des  collections d’objets, de  type  Ville. Les  classes de  type  Ville sont des classes en général, très simples, constituées par des méthodes de type setter/getter, appelées aussi  POJO (Plain Old Java Object). Le codage de ces classes DAO n’est pas complexe, mais s’avère très vite fastidieux, voire ennuyeux car répétitif. En  général, des méthodes nommées  getQuelqueChoseByAutreChose(…) encapsulent  des  requêtes SQL  du  type  « SELECT quelqueChose FROM table WHERE colonne=autreChose; ». La classe Ville : public class Ville implements Serializable { private String codePostal; private String nom; © ENI Editions – All rigths reserved – Kaiss Tag – 1 – enidentnumber-AAEAAAD/////AQAAAAAAAAAMAgAAAE1FTkkuRWRpdGlvbnMuTUVESUFwbHVzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAUBAAAAJ0VOSS5FZGl0aW9ucy5NRURJQXBsdXMuQ29tbW9uLldhdGVybWFyawIAAAAHcGlzVGV4dAlwaWR0ZURhdGUBAA0CAAAABgMAAAA5MzczMzc5IC0gS2Fpc3MgVGFnIC0gZWNhNTA5YTUtMDdkMC00NDU1LTgzYjItZGFmOTViNjc0ZWMzEcY1wqORzIgLAA==-enidentnumber public Ville() {} public Ville(String nom, String cp) { this.nom = nom; this.codePostal = cp; } public String getCodePostal() { return codePostal; } public void setCodePostal(String codePostal) { this.codePostal = codePostal; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String toString() { return this.nom +  » –  » + this.codePostal; } } Voici quelques extraits de la classe VilleDAO : public class VilleDAO { private DAO dao = null; public VilleDAO(DAO dao) { this.dao = dao; } public Collection getVillesByCodePostal(String cp) throws ApplicationDAOException { Collection villes = new ArrayList(); String sql = « SELECT * FROM codes_postaux WHERE cp=? »; Connection con = null; try { con = dao.getConnection(); PreparedStatement st = con.prepareStatement(sql); st.setString(1, cp); ResultSet rs = st.executeQuery(); while (rs.next()) { villes.add(this.construireVille(rs)); } } catch (SQLException e) { throw new ApplicationDAOException(e); } – 2 – © ENI Editions – All rigths reserved – Kaiss Tag enidentnumber-AAEAAAD/////AQAAAAAAAAAMAgAAAE1FTkkuRWRpdGlvbnMuTUVESUFwbHVzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAUBAAAAJ0VOSS5FZGl0aW9ucy5NRURJQXBsdXMuQ29tbW9uLldhdGVybWFyawIAAAAHcGlzVGV4dAlwaWR0ZURhdGUBAA0CAAAABgMAAAA5MzczMzc5IC0gS2Fpc3MgVGFnIC0gZWNhNTA5YTUtMDdkMC00NDU1LTgzYjItZGFmOTViNjc0ZWMzEcY1wqORzIgLAA==-enidentnumber finally { try { dao.releaseConnection(con); } catch (SQLException e) { } } return villes; } … } Vous  remarquerez  que  cette  classe  est  construite  sur  une  classe  DAO,  que  nous  présenterons  dans  la  section  suivante. Remarquez aussi que les exceptions levées sont d’un type propre à l’application ce qui permet de ne pas « polluer » les  autres couches de l’application par des Exceptions trop spécifiques qui exposent les APIs utilisées. En effet, la couche  DAO gère la persistance, si une exception d’une API de bas niveau remonte vers la couche métier ou la couche de  présentation,  on  supprime  le  couplage  faible  qui  doit  exister  entre  les  couches  de  l’application.  La  classe  ApplicationDAOException  vient  encapsuler  le  type  réel  de  l’exception.  Cette  classe  est  très  simple  et  permet  de  changer la couche DAO, qui peut générer d’autres types d’exceptions, sans impacter les couches utilisatrices. public class ApplicationDAOException extends Exception { private static final long serialVersionUID = 1L; public ApplicationDAOException() {} public ApplicationDAOException(String cause) { super(cause); } public ApplicationDAOException(Exception e) { super(e); } public ApplicationDAOException(String cause,Exception e) { super(cause,e); } } Le modèle général de codage utilisant JDBC est le suivant : ● obtention d’une connexion au serveur de base de données ; ● création d’une requête SQL ; ● exécution de la requête SQL ; ● traitement du jeu de résultat ; ● fermeture de la connexion. Le  codage des  classes DAO  est  toujours basé  sur le même  schéma,  symbolisé par l’acronyme CRUD  (Create,  Read,  Update and Delete) pour la création, la lecture, la mise à jour et la suppression des enregistrements en base.

Source de données et pool de connexion

Si le codage lui­même n’est pas complexe, il se pose malgré tout, très vite, dans les environnements distribués, un  problème important : comment gérer les connexions et déconnexions à la base de données. De manière classique, la  connexion et la déconnexion sont effectuées via la classe java.sql.DriverManager de JDBC. connexion = DriverManager.getConnection(url,user,pswd) C’est  donc  le  développeur  qui  gère  les  connexions.  Mais,  par  exemple  pour  un  site  web,  les  cycles  de  connexion/déconnexion peuvent être très fréquents et le nombre de connexions nécessaires à un instant donné, très  important. Ce mode de fonctionnement est donc inadapté. Pour  pallier  à  ce  problème,  les  serveurs  d’applications  fournissent  un  service  de  source  de  données  qui  utilise  un  mécanisme  de  pool  de  connexion.  Le  développeur  n’utilise  plus  le  DriverManager,  mais  une  classe  javax.sql.DataSource  qui  est  fournie  par  le  serveur.  Attention,  cette  classe  n’est  utilisable  que  dans  un  environnement qui peut la fournir, elle ne l’est pas dans une application autonome. Ce  n’est  plus  l’application  qui  gère  les  connexions,  c’est  le  serveur.  Le  serveur  maintient  un  certain  nombre  de  connexions qui sont physiquement connectées à la base de données, et qui sont distribuées au fur et à mesure des  besoins de l’application. L’appel de la méthode getConnection() permet de récupérer une connexion dans le pool. Une  connexion est remise dans le pool après un appel à la méthode close(), ou après un timeout. Les sources de données sont montées dans le nommage JNDI par le serveur. Pour utiliser une source de données, il  faut donc : ● effectuer une recherche JNDI ; ● demander une connexion. Une classe spécifique peut gérer les connexions et déconnexions à la base. C’est ici, la classe appelée DAO qui permet  d’encapsuler le type réel utilisé pour l’accès aux objets java.sql.Connection. En effet, une application non distribuée  utilisera  le  DriverManager,  tandis  qu’une  application  exécutée  au  sein  d’un  conteneur  utilisera  de  préférence  une  DataSource. public class DAO { String driver; String url; String user; String pswd; DataSource dataSource=null; public DAO(String driver, String url, String user, String pswd) throws ClassNotFoundException { this.driver = driver; this.url = url; this.user = user; this.pswd = pswd; Class.forName(driver); } public DAO(DataSource dataSource) { this.dataSource = dataSource; } public Connection getConnection() throws SQLException { Connection connexion = null; if(this.dataSource!=null) { connexion = this.dataSource.getConnection(); } else { connexion = DriverManager.getConnection(url,user,pswd); } – 4 – © ENI Editions – All rigths reserved – Kaiss Tag enidentnumber-AAEAAAD/////AQAAAAAAAAAMAgAAAE1FTkkuRWRpdGlvbnMuTUVESUFwbHVzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAUBAAAAJ0VOSS5FZGl0aW9ucy5NRURJQXBsdXMuQ29tbW9uLldhdGVybWFyawIAAAAHcGlzVGV4dAlwaWR0ZURhdGUBAA0CAAAABgMAAAA5MzczMzc5IC0gS2Fpc3MgVGFnIC0gZWNhNTA5YTUtMDdkMC00NDU1LTgzYjItZGFmOTViNjc0ZWMzEcY1wqORzIgLAA==-enidentnumber return connexion; } public void releaseConnection(Connection con) throws SQLException { con.close(); } } Les classes du modèle de VilleDAO vont demander à la classe DAO une connexion à la base. La classe DAO, en fonction  de  son  mode  de  construction,  par  une  DataSource,  ou  par  les  paramètres  de  connexion,  renverra  la  connexion  adéquate.

Formation et coursTélécharger le document complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *