Persistance d'Objets en Java : Guide Complet
Persistance d'Objets en Java : Guide Complet
La persistance d’objet
7
Sauvegarder les objets sans les dénaturer : la
sérialisation
La sérialisation est un mécanisme puissant en Java permettant de sauvegarder et de restaurer
des objets dans leur état d'origine, y compris leur structure et leurs relations. Cependant, bien
que la sérialisation soit une méthode pratique pour sauvegarder des objets, elle présente des
défis et des limitations qui nécessitent une compréhension approfondie pour une utilisation
efficace.
1. Principe de la sérialisation :
La sérialisation consiste à convertir un objet en une séquence d'octets, qui peuvent ensuite être
écrits dans un fichier ou transférés via le réseau. Lorsque vous sérialisez un objet, vous
enregistrez son état actuel, y compris les valeurs de ses attributs et ses relations avec d'autres
objets.
8
Sauvegarder les objets sans les dénaturer : la
sérialisation (2)
2. Limitations de la sérialisation :
Bien que la sérialisation offre une méthode pratique pour sauvegarder des objets, elle présente
certaines limitations. Tout d'abord, elle ne préserve pas la structure objet des données
sauvegardées. Les valeurs des attributs sont enregistrées de manière indépendante, sans tenir
compte de la structure objet sous-jacente. De plus, la sérialisation ne gère pas automatiquement
les relations entre les objets. Si un objet référence un autre objet, seule l'adresse de l'objet
référencé est sauvegardée, sans sauvegarder l'objet lui-même.
11
Explication du code
1. Création d'un flux de sortie vers un fichier :
FileOutputStream fichierOut = new FileOutputStream("personne.ser");
Cette instruction crée un flux de sortie vers un fichier nommé "personne.ser". Cela permettra
d'écrire les données sérialisées de l'objet Personne dans ce fichier.
2. Création d'un objet ObjectOutputStream :
ObjectOutputStream objOut = new ObjectOutputStream(fichierOut);
Cette instruction crée un objet ObjectOutputStream, qui est utilisé pour écrire des objets
sérialisés dans un flux de sortie. Dans ce cas, le flux de sortie est celui que nous avons créé
précédemment vers le fichier "personne.ser".
3. Sérialisation de l'objet Personne :
objOut.writeObject(personne);
Cette instruction utilise l'objet ObjectOutputStream pour sérialiser l'objet Personne. Cela signifie
que les données de l'objet (ici, les valeurs de ses attributs) sont converties en une séquence
d'octets et écrites dans le fichier spécifié.
13
Explication du code (2)
4. Fermeture de l'objet ObjectOutputStream et du fichier de sortie :
objOut.close();
fichierOut.close();
Ces instructions ferment respectivement l'objet ObjectOutputStream et le flux de sortie vers le
fichier. Cela libère les ressources utilisées par ces objets et garantit que toutes les données ont
été écrites correctement dans le fichier.
Ensemble, ces instructions permettent de sérialiser l'objet Personne et d'écrire ses données
sérialisées dans un fichier.
14
Explication du code (3)
La méthode writeObject() de la classe ObjectOutputStream effectue plusieurs actions lorsqu'elle
est appelée :
1. Elle vérifie si l'objet à sérialiser implémente l'interface Serializable. Si l'objet ne le fait pas, une
exception de type NotSerializableException est levée.
2. Elle sérialise l'objet, c'est-à-dire qu'elle convertit l'état de l'objet en une séquence d'octets, en
suivant un processus défini par les règles de sérialisation de Java. Cette séquence d'octets
représente l'état de l'objet de manière à ce qu'il puisse être stocké dans un fichier, envoyé via le
réseau ou autrement persisté.
3. Elle écrit la séquence d'octets résultante dans le flux de sortie associé à l'objet
ObjectOutputStream. Le flux de sortie peut être un fichier, un flux réseau ou tout autre support
de stockage des données.
15
Illisibilité des fichiers de sérialisation
1. Puissance de la sérialisation :
La sérialisation est présentée comme un mécanisme simple mais puissant pour sauvegarder et
restaurer des objets en Java. Elle est louée pour sa capacité à préserver la nature orientée objet
des données et à gérer automatiquement les relations entre les objets lors de la sérialisation et
de la désérialisation.
2. Lisibilité des fichiers de sérialisation :
Cependant, l'un des principaux inconvénients de la sérialisation est son manque de lisibilité, en
particulier dans sa version binaire. Les fichiers de sérialisation générés sont illisibles pour un
utilisateur humain. Même en ouvrant le fichier avec un éditeur de texte comme le bloc-notes de
Windows, les données sérialisées apparaissent sous forme de caractères non lisibles.
3. Exclusivité de lecture par les programmes :
La sérialisation crée des fichiers de données qui ne peuvent être compris et interprétés que par
des programmes Java, C#, Python, ou d'autres langages de programmation qui prennent en
charge la sérialisation. Les données sérialisées ne sont pas facilement accessibles et lisibles pour
un utilisateur humain sans le recours à un programme informatique.
16
Illisibilité des fichiers de sérialisation (2)
En résumé, bien que la sérialisation soit efficace pour sauvegarder des objets en Java, elle
présente des limitations en termes de lisibilité des fichiers résultants, ce qui peut rendre difficile
l'accès aux données sérialisées sans l'utilisation de programmes informatiques spécifiques. Les
bases de données sont proposées comme une alternative plus lisible et largement utilisée pour
la persistance des données.
17
Les bases de données relationnelles
- Les bases de données relationnelles sont largement utilisées pour stocker des informations de
manière permanente.
- Malgré l'attrait de la programmation orientée objet, les bases de données relationnelles restent
prédominantes.
- Les données dans ces bases sont organisées de manière similaire aux objets en programmation
orientée objet, avec des structures de type "objet" regroupées dans des tables.
- L'organisation relationnelle évite la duplication des informations, ce qui facilite les mises à jour
et réduit les erreurs d'encodage.
- Les tables codent des concepts distincts et sont liées entre elles par des relations, similaires aux
liens d'association entre les classes en programmation orientée objet.
- Les bases de données relationnelles offrent de nombreuses solutions techniques pour gérer les
problèmes critiques tels que les sauvegardes automatiques, les accès concurrentiels, sécurisés et
transactionnels, ainsi que le stockage réparti sur plusieurs ordinateurs.
18
Structured Query Language (SQL)
SQL (Structured Query Language) est un langage standardisé utilisé
pour interroger les bases de données relationnelles.
- Toute application informatique qui interagit avec une base de données
relationnelle utilise le langage SQL.
- Les environnements logiciels populaires tels qu'Oracle, Informix,
Sybase ou Access offrent des solutions techniques pour la gestion des
bases de données relationnelles.
- Les bases de données relationnelles, combinées avec le langage SQL et
les solutions logicielles, sont devenues indispensables pour la
persistance des objets dans les applications informatiques.
19
Structured Query Language (SQL) (2)
Le langage SQL est utilisé pour interagir avec les bases de données, permettant la création de
tables et de relations, ainsi que la consultation, l'insertion, la suppression et la modification des
enregistrements. Voici quelques instructions couramment utilisées :
- SELECT: Utilisé pour lire les enregistrements d'une table en spécifiant les colonnes à afficher et
les tables à partir desquelles lire, avec éventuellement une condition logique pour filtrer les
résultats.
- INSERT: Permet d'insérer de nouveaux enregistrements dans une table en spécifiant les valeurs
à ajouter pour chaque colonne.
- UPDATE: Utilisé pour mettre à jour des enregistrements existants dans une table en modifiant
les valeurs des colonnes spécifiées, éventuellement en fonction d'une condition.
- DELETE: Permet d'effacer des enregistrements d'une table en spécifiant une condition pour
filtrer les enregistrements à supprimer.
Ces instructions SQL sont fondamentales pour manipuler les données dans les bases de données
20
relationnelles.
Une table une classe...
Lorsque nous sauvegardons des informations dans une table de base de données, nous pouvons
les comparer à une classe en programmation orientée objet (OO). Imaginons que nous voulions
sauvegarder les informations sur des produits dans une table appelée "Produit" dans une base
de données Microsoft Access.
Dans cette table, chaque enregistrement représente un produit et chaque colonne représente un
attribut du produit, tel que son nom, sa catégorie, son prix, etc. Cependant, il y a un attribut
supplémentaire appelé "clé primaire", nommé ici "idProduit", qui n'existerait pas dans une
approche orientée objet.
La "clé primaire" est un attribut unique pour chaque enregistrement dans la table. Elle permet
d'identifier de manière unique chaque produit dans la base de données. Cela correspond à un
identifiant unique que l'on utiliserait dans une classe en programmation orientée objet pour
accéder à une instance particulière de cette classe.
21
Une table une classe... (2)
Lorsque nous avons besoin de récupérer des informations sur un produit spécifique dans la base
de données, nous utilisons la valeur de la clé primaire (idProduit) pour retrouver
l'enregistrement correspondant. Le système de gestion de base de données utilise cette valeur
pour localiser et récupérer l'enregistrement unique associé à cette clé primaire.
Clé primaire
La clé primaire d'une table est un attribut qui permet d'identifier de manière unique et sans
ambiguïté chaque enregistrement dans cette table. Chaque enregistrement doit avoir une valeur
distincte pour cet attribut, garantissant ainsi son unicité. Habituellement, la valeur de la clé
primaire est un nombre entier, bien que d'autres types de données puissent également être
utilisés.
22
Différences dans la gestion des clés primaires entre
la programmation orientée objet et les bases de
données relationnelles
Dans le contexte des classes en programmation orientée objet, la raison pour laquelle la classe
Produit n'inclut pas d'attribut similaire à la clé primaire est que cette classe n'a pas besoin d'un
mécanisme interne pour accéder à ses instances de la même manière que dans une base de
données relationnelle.
En programmation orientée objet, chaque instance de la classe Produit est généralement
retrouvée par l'utilisation de variables référentes, qui contiennent l'adresse physique de
l'instance en mémoire. Dans ce paradigme, l'objectif principal est de manipuler des variables et
des objets en mémoire vive pour accéder aux informations stockées.
En revanche, les bases de données relationnelles sont principalement des systèmes de stockage
d'informations fiables et économiques. Elles utilisent des clés primaires pour garantir l'unicité
des enregistrements et permettre un accès efficace à ces derniers. Cependant, dans cet
environnement, le concept de référents basé sur des adresses physiques n'est pas pertinent car
les données sont stockées de manière différente, sur un disque dur par exemple, et non en
mémoire vive. 23
Différences fondamentales entre la gestion des
données en bases de données relationnelles et en
programmation orientée objet
Dans le contexte des bases de données relationnelles par rapport à la
programmation orientée objet, la différence fondamentale réside dans la façon
dont les données sont manipulées et stockées.
Dans une base de données relationnelle, chaque produit doit être associé à un identifiant unique, similaire à un
numéro d'identification dans un passeport ou une carte d'identité. Cela garantit que chaque produit peut être
retrouvé de manière spécifique et fiable dans la base de données. En revanche, dans le contexte de la
programmation orientée objet, les objets produit n'ont pas besoin d'un identifiant unique de ce type, car leurs
utilisateurs peuvent les retrouver en connaissant leur référent, c'est-à-dire leur adresse en mémoire.
Ainsi, les référents sont essentiels dans le contexte de la programmation orientée objet, car leur absence pourrait
rendre un objet inaccessible. En revanche, dans une base de données relationnelle, la clé primaire garantit l'unicité
et l'accès aux enregistrements, mais n'a pas besoin de correspondre à une adresse physique.
26
Comment Java et C# s’interfacent aux bases de
données
En Java et en C#, l'accès aux bases de données est simplifié grâce à l'utilisation de méthodes et de
bibliothèques spécifiques. Ces langages de programmation offrent des fonctionnalités intégrées pour
se connecter à des bases de données, exécuter des requêtes SQL et récupérer les résultats. Par
exemple, en Java, des bibliothèques telles que JDBC (Java Database Connectivity) sont largement
utilisées pour interagir avec des bases de données relationnelles.
Cependant, il convient de noter que C++ n'intègre pas nativement l'accès aux bases de données dans
sa syntaxe de base. Bien que les mêmes fonctionnalités puissent être réalisées en C++, elles
nécessitent l'utilisation de fonctionnalités supplémentaires proposées par le système d'exploitation
et le pilote de la base de données.
En ce qui concerne Python, bien que sa bibliothèque standard ne fournisse pas actuellement
d'interface universelle à toutes les bases de données relationnelles, de nombreux modules tiers sont
disponibles pour permettre aux programmes de se connecter à différentes bases de données telles
que DB2, MySQL, Informix, Microsoft SQL Server, Adabas, Sybase, etc.
Ainsi, alors que Java et C# offrent des fonctionnalités intégrées pour interagir avec les bases de
données, C++ nécessite des extensions, tandis que Python peut être étendu grâce à des modules
27
tiers pour accéder à diverses bases de données relationnelles.
Relations entre tables et associations entre classes
Les relations entre tables et les associations entre classes sont des
concepts fondamentaux dans le développement logiciel, surtout lorsque
l'on travaille avec des bases de données relationnelles et des langages
de programmation orientés objet (OO). Voici une explication détaillée de
ces concepts :
Relations entre tables :
Lorsque nous travaillons avec des bases de données relationnelles, les
données sont stockées dans des tables. Ces tables sont souvent liées les
unes aux autres par des relations, ce qui permet de représenter les
associations entre différentes entités dans le système.
30
Relations entre tables et associations entre classes
(2)
Relation 1-n (un-à-plusieurs) :
Cette relation décrit le cas où une entité dans une table est associée à plusieurs entités dans une
autre table, mais chaque entité de la seconde table est associée à une seule entité de la
première table.
Par exemple, considérons deux entités : "Produit" et "Stock". Un produit peut être stocké dans
plusieurs emplacements, mais chaque emplacement ne contient qu'un seul produit.
En programmation orientée objet, cela peut être représenté par une classe "Produit" contenant
une liste de références vers des objets "Stock".
En base de données relationnelle, cela se traduit par deux tables distinctes : une pour les
produits et une pour les emplacements de stockage. Pour établir la relation, la table des
emplacements de stockage inclut une clé étrangère qui fait référence à la clé primaire des
produits.
L'intégrité référentielle peut être utilisée pour garantir que seuls les produits existants peuvent
être associés à des emplacements de stockage. 31
https://www.coodemaroc.com/2021/06/bases-de-
donnees.html
Relations entre tables et associations entre classes
(3)
En programmation orientée objet, les associations entre classes définissent les
relations et les interactions entre les objets. Ces associations peuvent être de
différents types, tels que l'agrégation, la composition, l'association simple, etc.
Chaque type d'association a ses propres caractéristiques et règles.
Agrégation :
Dans une application de gestion de bibliothèque, une classe "Bibliothèque" peut
être associée à une classe "Livre". La relation entre ces deux classes est une
agrégation, car une bibliothèque peut contenir plusieurs livres.
Composition :
Dans une application de modélisation de véhicules, une classe "Véhicule" peut être
composée de plusieurs instances de la classe "Roue". La relation entre ces deux
classes est une composition, car les roues font partie intégrante du véhicule et sont
créées et détruites en même temps que lui. 33
Relations entre tables et associations entre classes
(4)
Association simple : Dans une application de gestion d'étudiants, une classe
"Etudiant" peut être associée à une classe "Cours". La relation entre ces deux
classes est une association simple, car un étudiant peut être inscrit à plusieurs
cours et un cours peut avoir plusieurs étudiants inscrits.
En résumé, les relations entre tables et les associations entre classes sont des
concepts essentiels pour modéliser les données et les interactions dans les
systèmes logiciels, que ce soit dans le contexte des bases de données relationnelles
ou de la programmation orientée objet. Ces concepts permettent de représenter
de manière efficace les relations complexes entre les entités
34
Relations entre tables et associations entre classes
(5)
Relation n-n (plusieurs-à-plusieurs) :
Dans le contexte des bases de données relationnelles, la relation n-n (many-to-many) entre deux
tables est généralement gérée en utilisant une table intermédiaire, également appelée table de
jointure. Cette approche est nécessaire car les bases de données relationnelles ne permettent
pas directement la création de relations many-to-many entre deux tables.
• Prenons l'exemple de deux entités, par exemple "Étudiant" et "Cours", qui ont une relation
many-to-many. Un étudiant peut s'inscrire à plusieurs cours, et un cours peut être suivi par
plusieurs étudiants.
• Plutôt que de tenter de représenter directement cette relation dans les tables des étudiants et
des cours, ce qui serait difficile à gérer en raison des contraintes de clés étrangères multiples,
on crée une troisième table, souvent appelée table de liaison ou table de jointure. Cette table
contient généralement les clés primaires des deux tables en relation.
35
Relations entre tables et associations entre classes
(6)
• Par exemple, une table de jointure entre "Étudiant" et "Cours" pourrait s'appeler
"Inscriptions" et contenir les colonnes suivantes :
• OQL est conçu pour être étroitement intégré avec des langages de
programmation orientée objet tels que Java ou C++. Il permet aux développeurs
d'exprimer des requêtes en utilisant des concepts familiers de la POO, tels que
les classes, les attributs et les méthodes. Ainsi, les requêtes OQL peuvent être
intégrées de manière transparente dans le code source d'une application
orientée objet, ce qui facilite la manipulation des données stockées dans la base
41
de données.
Conclusion
• Les "Objets sains et saufs" représentent le besoin des objets informatiques de
maintenir leur état entre deux exécutions du programme.
• Les bases de données orientées objet (OO) offrent une solution attrayante pour
cette problématique, grâce à leur facilité d'accès, leur transparence de sauvegarde
et leur capacité à préserver la structure des objets ainsi que leurs relations.
• Ces bases de données permettent de stocker les objets de manière persistante sur
le disque tout en conservant leur nature objet, facilitant ainsi leur accès et leur
manipulation dans un environnement orienté objet.
• En attendant une adoption généralisée des bases de données orientées objet, des
initiatives telles que SQL3 visent à fournir des fonctionnalités avancées pour
modéliser les relations entre entités dans un environnement orienté objet.
• L'objectif ultime est de pouvoir manipuler de manière transparente, dans un
programme orienté objet, à la fois les enregistrements de bases de données et les
objets stockés sur le disque, mais cela reste incertain et dépendra de l'évolution
future de la technologie. 42
Les références
• https://jmdoudoux.developpez.com/cours/developpons/java
/chap-persistence.php
• https://laravel.sillo.org/cours-laravel-6-les-donnees-la-
relation-1n/
• https://sql.sh/
• https://lig-
membres.imag.fr/donsez/cours/bdsqll3etobjet.pdf
43
44