Gestion de la persistance des objets CSC4002 Claire Lecocq 2012
Plan du document Motivations Application exemple : la médiathèque Problématique en image Quel schéma de Base de Données Relationnelle ? Gérer la persistance dans Java : JDBC 2012
Application exemple : la médiathèque Développement objet : standard de fait Où sont stockées les données ? Durée de vie ? Partage ? Volume de données ? Une idée ? A la fin d’une session d’utilisation d’une application orientée objet toutes les données des objets existant dans la mémoire vive de l’ordinateur sont perdues Pour année prochaine : ce slide est trop facile/ trop lent. A revoir 2012
Problématique en image Application UML Développement Objet Mapping chargement déchargement Rendre persistant un objet c’est sauvegarder ses données sur un support non volatile de telle sorte qu’un objet identique à cet objet puisse être recréé lors d’une session ultérieure Les paradigmes objet et relationnel sont bien distincts Le paradigme objet est plus riche Dès qu’un modèle objet est complexe (de l’héritage et beaucoup d’associations) il n’est pas simple de faire correspondre des objets et des tables relationnelles Un objet a une structure complexe qui peut être représentée par un graphe Le plus souvent ce graphe est un arbre dont la racine correspond à l’objet et les fils correspondent aux valeurs des variables d’instance qui sont persistantes Il faut « aplatir » ce graphe pour le ranger dans la base de données relationnelle sous une forme tabulaire Stockage des données Modèle E/A Relationnel SGBD 2012
Plan du document Motivations Quel schéma de Base de Données Relationnelle ? Processus de conception d’une BD (rappel) Entité/Association versus diagramme de classes UML Existe t-il un modèle relationnel pour un diagramme de classes ? Diagramme de classes de la médiathèque Revenons sur la sémantique de l’héritage1 Traduction de l’héritage en modèle relationnel Gérer la persistance dans Java : JDBC 1 la généralisation/spécialisation est appelée dans ce cours héritage 2012
Processus de conception d’une BD (rappel) Monde réel Indépendant du SGBD Recueil des besoins et analyse Besoin de la BD Contrat Prise en compte des particularités du SGBD Conception logique Schéma conceptuel (haut niveau) E/A UML Transformation du modèle Spécifique à un SGBD Relationnel Réseau Hiérarchique Schéma conceptuel (spécifique SGBD) Conception physique Placement Disque Optimisation Schéma physique (spécifique SGBD) 2012
Entité/Association versus diagrammes de classes et d’objets UML Modèles de conception Entité/Association versus diagrammes de classes et d’objets UML SI-BD Entité/Association Génie logiciel - langages Diagramme de classe Entité Classe Entité faible Composition Association sans attribut Association Association avec attribut(s) Classe d’association (Héritage), association « est un » << Héritage – Généralisation, spécialisation Clé Identité d’objet Attribut calculé Attribut dérivé Opération Cardinalités Cardinalités, multiplicités Attribut d’une entité de paramètres Attributs de classe 2012
Existe t-il un modèle relationnel pour un diagramme de classes ? Si Hypothèse 1 : existe correspondance E/A diagramme de classes Hypothèse 2 : existe traduction E/A relationnel Alors Transformer un diagramme de classes UML (partie statique) en un schéma relationnel « équivalent » peut se ramener à la transformation d’un schéma E/A vers un schéma relationnel Problème hypothèse 1 : héritage 2012
Diagramme de classes de la médiathèque 2012
Revenons sur la sémantique de l’héritage Classe enfant hérite des attributs de sa classe parent Spécialisation peut être : Totale ou partielle : Totale : toute instance est spécialisée dans au moins une classe enfant Classe abstraite Partielle : une instance peut ne pas être spécialisée Une partition ou un recouvrement : Partition : une instance est spécialisée dans au plus une classe enfant Recouvrement : une instance peut être spécialisée dans plusieurs classes enfants Héritage multiple Personne nom prénom adresse Personne = Etudiant Salarie Etudiant Salarié X Totale Recouvrement Pour année prochaine Développer en donnant d’autres exemples . Classification animale par exemple. Autres slides Etudiant noEtud cycle Salarie salaire Totale Partition Prive prime Public indice Doctorant vacataire Salarie = Prive Public Prive Public = 2012
Traduction de l’héritage en modèle relationnel 3 correspondances possibles : Correspondance directe Correspondance ascendante Correspondance par aplatissement 3.1. Pour partition 3.2. Pour recouvrement Ne s’appliquent pas à toutes les typologies d’arbre d’héritage totale/partielle partition/recouvrement 2012
Correspondance directe (n° 1) Une classe une relation BD Liaison entre les relations se fait via la clé Correspondance de l’arbre de Document Document code titre auteur annee empruntable emprunte nbEmprunts Création d’une clé Relation clé Contrainte d’intégrité référentielle Audio code classification Video code dureeFilm mentionLegale Livre code nbPages Clé + clé étrangère 2012
Correspondance directe (n° 1) - suite Document code titre auteur annee empruntable emprunte nbEmprunts Typedoc Classification nombrePages Durrefilm Mentionlegale create view vueDocument(code, titre, auteur, annee, empruntable, emprunte, salle,rayon,nomGenre,nbEmprunts, typedoc, classification, nombrePages, dureeFilm, mentionLegale) as select document.code, titre, auteur, annee, empruntable, emprunte, salle,rayon,nomGenre,nbEmprunts,'Audio', classification, null, null, null from audio, document where audio.code = document.code union select document.code, titre, auteur, annee, empruntable, emprunte, salle,rayon,nomGenre,nbEmprunts,'Video', null, null, dureeFilm, mentionLegale from video, document where video.code = document.code select document.code, titre, auteur, annee, empruntable, emprunte, salle,rayon,nomGenre,nbEmprunts,'Livre', null, nombrePages, null, null from livre, document where livre.code = document.code ; Document code titre auteur annee empruntable emprunte nbEmprunts Relation clé Vue Audio code classification Video code dureeFilm mentionLegale Livre code nbPages Contrainte d’intégrité référentielle Construction de la vue par requête 2012
Correspondance directe pour la médiathèque Document code titre … Dénormalisation Audio code classification FicheEmprunt nom prenom code dateEmprunt dateLimite depasse Client nom prenom adresse nbEmpruntsEffectues nbEmpruntsDepasses nbEmpruntsEnCours catclient dateInscription codeReduction dateRenouvellement Document code titre auteur annee empruntable emprunte nbEmprunts nomGenre salle rayon Video code dureeFilm mentionLegale Categorie nom nbEmpruntsMax tarifInscription coefDuree coefTarif codeReducUsed Livre code nbPages Localisation salle rayon Genre nom nbEmprunts Solution retenue pour le TP 2012
Correspondance directe et typologie des arbres d’héritage Spécialisation Remarques Totale Partielle Partition Recouvrement OK Vérification : 1 tuple de la « relation parent » est toujours référencé par 1 tuple de la « relation enfant » Vérification : non duplication de clé entre « relations enfants » Reconstitution de l'objet par jointure Sémantique très proche du modèle objet Fonctionne quelle que soit la typologie d’arbre d’héritage 2012
Correspondance ascendante (n° 2) Chaque classe spécialisée une relation BD Classe parent une vue Correspondance de l’arbre de Document Document code titre auteur annee empruntable emprunte nbEmprunts CREATE VIEW Document AS SELECT code, titre, auteur, annee, empruntable, emprunte, nbEmprunts FROM Audio UNION SELECT code, titre, auteur, annee, empruntable, emprunte, nbEmprunts FROM Video UNION SELECT code, titre, auteur, annee, empruntable, emprunte, nbEmprunts FROM Livre Audio code titre auteur annee empruntable emprunte nbEmprunts classification Video code titre auteur annee empruntable emprunte nbEmprunts dureeFilm mentionLegale Livre code titre auteur annee empruntable emprunte nbEmprunts nbPages Vue Construction de la vue par requête 2012
Correspondance ascendante pour la médiathèque Une vue n’est pas une relation BD ! Pas de clé, non référençable par une clé étrangère FicheEmpruntAudio code nom prenom Audio code FicheEmpruntVideo code nom prenom Document code Video code Client nom prenom FicheEmpruntLivre code nom prenom Livre code FicheEmprunt 2012
Correspondance ascendante et typologie des arbres d’héritage Spécialisation Remarques Totale Partielle Partition Recouvrement OK KO Redondance de données Multiplie les relations Évite les jointures pour reconstruire les objets Spécialisation totale. Classe abstraite = vue (relation virtuelle) Pas possible d’assurer simplement l’unicité des identificateurs Polymorphisme : capacité d’une objet a se comporter comme objets de plusieurs formes : audio et Document 2012
Correspondance par aplatissement (n° 3.1) Ensemble des classes de la hiérarchie une seule relation BD Éventuellement chaque classe une vue Correspondance de l’arbre de Document Document code titre auteur annee empruntable emprunte nbEmprunts typeDocument classification dureeFilm mentionLegale nbPages CREATE VIEW Audio AS SELECT code, titre, auteur, annee, empruntable, emprunte, nbEmprunts, classification FROM Document WHERE typeDocument=‘Audio’ Audio code … classification Video code … dureeFilm mentionLegale Livre code … nbPages 2012
Correspondance par aplatissement 3.1 pour la médiathèque FicheEmprunt nom prenom code dateEmprunt dateLimite depasse Client nom prenom adresse nbEmpruntsEffectues nbEmpruntsDepasses nbEmpruntsEnCours typeClient dateInscription dateRenouvellement codeReduction dateCotisation Genre nom nbEmprunts Document code titre auteur annee empruntable emprunte nbEmprunts nomGenre salle rayon typeDocument classification dureeFilm mentionLegale nbPages Localisation salle rayon Categorie nom nbEmpruntsMax tarifInscription coefDuree coefTarif codeReducUsed Solution retenue pour le TP 2012
Si attribut donnant le nom de la classe autorisé à null Correspondance par aplatissement 3.1 et typologie des arbres d’héritage Spécialisation Remarques Totale Partielle Partition Recouvrement OK Si attribut donnant le nom de la classe autorisé à null KO Évite les jointures pour reconstruire les objets Du vide dans la relation (valeurs nulles) ... Spécialisation totale : classes abstraites relations (concrètes), classes concrètes vues (virtuelles) Souvent la solution la plus simple à mettre en place; la plus choisie 2012
Correspondance par aplatissement 3.2 pour la médiathèque Variante de la correspondance 3.1 avec utilisation d’un attribut booléen supplémentaire par classe enfant Si un document pouvait être à la fois un Audio et une Vidéo … Document code titre auteur annee empruntable emprunte nbEmprunts AudioB VideoB LivreB Classification dureeFilm mentionLegale nbPages CREATE VIEW Audio AS SELECT code, titre, auteur, annee, empruntable, emprunte, nbEmprunts, classification FROM Document WHERE AudioB = 1 2012
Correspondance par aplatissement 3 Correspondance par aplatissement 3.2 et typologie des arbres d’héritage Spécialisation Remarques Totale Partielle Partition Recouvrement OK Si tous les attributs booléens correspondant aux classes enfants sont autorisés à NULL Non pertinent idem 3.1 2012
Plan du document Motivations Quel schéma de Base de Données Relationnelle ? Gérer la persistance dans Java : JDBC Qu’est ce que JDBC ? Que faire pour pouvoir utiliser JDBC ? Étapes d’interaction avec le SGBD Politique de gestion de la persistance 2012
Qu’est ce que JDBC ? Java DataBase Connectivity API Java pour accéder à des SGBDR via SQL Indépendance / SGBD cible (via des pilotes) Fourni par le paquetage java.sql Interfaces Implémentées dans les pilotes (en anglais driver) Dépendants des SGBDs cibles « Tout » SGBD a un pilote JDBC 4 catégories de pilotes en fonctions de : La présence ou non de pilote SGBD (non Java) sur le client Protocole de communication entre le client Java et le serveur Application java Pilote Protocole du SGBD SGBD Type 4 2012
Que faire pour pouvoir utiliser JDBC ? Avoir un pilote Le référencer dans le CLASSPATH Dans chaque classe qui utilise des ordres JDBC Importer le paquetage java.sql import java.sql.*; Charger en mémoire la classe du (des) pilote(s) avant d’utiliser JDBC : Class.forName("oracle.jdbc.OracleDriver"); Class.forName("com.mysql.jdbc.Driver" ); Class.forName("org.postgresql.Driver" ); 2012
Étapes d’interaction avec le SGBD Ouvrir une connexion Instance de Connection Créer des « fils » pour supporter l’envoi d’instructions SQL au sein de la connexion Requête dans une instance de Statement, PreparedStatement ou CallableStatement Demander l’exécution de ces instructions par le SGBD : Requête d’interrogation (SELECT) : méthode executeQuery() sur le *Statement Requête de mise à jour (INSERT, UPDATE, DELETE) : méthode executeUpdate() sur le *Statement autre ordre SQL (appel de procédure stockée) : execute() sur le *Statement Fermer la connexion : méthode close() sur la connexion 2012
Connection versus Statement Application java SGBD PostgresSQL Media : Mediatheque Statement statement1 « SELECT * FROM Document » Nom : string …. Connection : @Connection Pilote MySQL Statement statement2 Constructeur() rechercheBD() miseAJourBD() Destructeur() Statement statement3 2012
1. Établir une connexion String driver = "org.postgresql.Driver"; String urlBd = "jdbc:postgresql://mysql-inf/TPCONCEPTION"; try { Class.forName(driver).newInstance(); }catch(Exception cnfe) { throw new OperationImpossible("Echec acces Pilote BD- " + driver + " " + cnfe); } Statement stmt = null; laConnexion = DriverManager.getConnection(urlBd,compte,passe); } catch(SQLException qe) { throw new OperationImpossible("Echec connexion BD- " + qe + " " + urlBD); 2012
2 et 3. Exécuter une requête SELECT try { stmt = laConnexion.createStatement(); ResultSet rset = stmt.executeQuery ("select * from localisation"); while (rset.next()) { String s = rset.getString("salle"); String r = rset.getString("rayon"); Localisation loc = new Localisation(s,r); lesLocalisations.addElement(loc); } } catch(SQLException se) { throw new OperationImpossible("Echec acces Localisation- " +se.getMessage()); 2012
2 et 3. Exécuter une requête SELECT Méthode executeQuery() executeQuery() renvoie une instance de ResultSet L’instance de ResultSet se parcourt itérativement ligne par ligne Les colonnes sont référencées par leur numéro ou par leur nom L'accès aux valeurs des colonnes se fait par les méthodes getXXX() où XXX représente le type de l'objet ou bien par un getObject() suivi d’une conversion explicite 2012
Correspondance de type SQL/Java 2012
2 et 3. Exécuter une requête de mise à jour (1) private void insererBD(Document doc) throws perationImpossible { try { PreparedStatement stmt = null; if(doc instanceof Audio ){ Audio au = (Audio) doc; stmt = laConnexion.prepareStatement("INSERT INTO document (code, titre, auteur, annee, empruntable, emprunte, salle, rayon, nomgenre, nbemprunts, typedoc, classification) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Audio', ?)"); stmt.setString(11, au.getClassification()); } else { // Video puis Livre } 2012
2 et 3. Exécuter une requête de mise à jour (2) stmt.setString(1, doc.getCode()); stmt.setString(2, doc.getTitre()); stmt.setString(3, doc.getAuteur()); stmt.setString(4, doc.getAnnee()); stmt.setInt(5,doc.estEmpruntable()?1:0); stmt.setInt(6, doc.estEmprunte()?1:0); stmt.setString(7, doc.getLocalisation().getSalle()); stmt.setString(8, doc.getLocalisation().getRayon()); stmt.setString(9, doc.getGenre().getNom()); stmt.setInt(10, doc.getNbEmprunts()) } catch (SQLException e) { throw new OperationImpossible("Echec insertion BD- " + e); } 2012
Politique de gestion de la persistance Comment intégrer le code JDBC qui assure le chargement et le déchargement des objets Java depuis la BD En structurant au mieux le code (limiter le nombre d’opérations à modifier) Quel(s) objet(s) charger et quand ? Quel(s) objet(s) décharger et quand ? 2012
Chargement / déchargement (1) Constructeur d’objet intégrant tous les attributs Statique : constructeur de « collections » Similaire au TP médiathèque sérialisée Volume de données contrôlé Dynamique : constructeur d’objet (nécessité d’une clé pour sélectionner l’objet) Charger les objets connexes Déchargement Statique : à la fin du programme (attention aux pertes d’infos) Dynamique : dans les opérations de mise à jour En étant plus rapide au début on pourrait développer ces points sur des grandes applications (SNCF, etc…) 2012
Chargement / déchargement (2) Statique Adapté aux petits volumes de données Faible taux de mises à jour Simple à mettre en œuvre Dynamique Adapté aux volumes de données importants Fort taux de mises à jour Meilleure résistance aux fautes Plus compliqué à programmer 2012