Java:Persistance

De Wiki Fred
Aller à : navigation, rechercher

__NOTITLE__

Persistance des données en Java


Description


Une des tâches les plus importante dans une application est de sauvegarder et de récupérer des données. Gérer cela soi-même est fastidieux, complexe, difficile à maintenir et finalement ingérable.

Heureusement, Java offre divers mécanismes permettant de rendre les données persistantes.

Sérialisation


Le mécanisme de sérialisation de Java permet, très facilement, de rendre persistantes les données d'une classe.

  • Implémenter l'interface java.io.Serializable et générer un serialVersionUID
1 import java.io.Serializable;
2 
3 public class Student implements Serializable
4 {
5 	private static final long serialVersionUID = -5369427371356860465L;
6 
7 	private int    mantricule;
8 	private String name;
9 }
  • Sérialisation d'un objet dans un fichier Student.data
 1 Student st = new Student();
 2 st.setMantricule(123456789);
 3 st.setName("John Smith");
 4 			
 5 FileOutputStream   fos = new FileOutputStream("Student.data");
 6 		
 7 ObjectOutputStream oos = new ObjectOutputStream(fos);
 8 		
 9 oos.writeObject(st);
10 		
11 oos.close();
  • Dé-sérialisation d'un objet à partir d'un fichier Student.data
1 FileInputStream   fis = new FileInputStream("Student.data");
2 		
3 ObjectInputStream ois = new ObjectInputStream(fis);
4 		
5 Student st = (Student) ois.readObject();
6 		
7 ois.close();


Object-Relational Mapping (ORM)


Le principe du mapping objet-relationnel consiste à déléguer l'accès aux données à des outils ou frameworks externes et de proposer une vue orientée objet d'une structure de données relationnelles.

Exemples d'outils ou de frameworks permettant de mettre en œuvre ou utilisant cette technique :

  • Java Data Base Connectivity
  • Java Persistence API
  • iBATIS
  • Hibernate
  • Java Data Objects


JDBC


Java Data Base Connectivity (JDBC) est la couche logicielle standard offerte aux développeurs pour accéder à des bases de données relationnelles.

Cette API fait partie intégrante de la plate-forme Java (SE) depuis la version 1.1 et est définie dans le package java.sql.

L'implémentation de cette interface est de la responsabilité du driver de la base de données.

Mise en oeuvre avec MySQL


  • Ajouter la dépendance maven pour le driver
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.18</version>
</dependency>
  • Création d'une connection
1 Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1/mydb","user","password");


  • Pour Java < 1.6 il faut charger manuellement le driver avant de créer la connection
1 Class.forName("com.mysql.jdbc.Driver");
Si le driver ne se trouve pas dans le build path de l'application
Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
  • A partir de l'API JDBC 4.0 (apparue dans Java 1.6) cette étape n'est plus indispensable. Le driver le plus approprié sera chargé automatiquement.
Si aucun driver ne peut être trouvé
Exception in thread "main" java.sql.SQLException: No suitable driver for jdbc:mysql://127.0.0.1/mydb
 


  • Envoi d'une requête sql
1 Statement stmt = connection.createStatement();
2 ResultSet rs = stmt.executeQuery("select * from ...");
  • Utilisations du résultat
1 while(rs.next())
2 {
3   System.out.println(rs.getInt("id"));
4   ...
5 }


Java Persistance API (JPA)


JPA est une API Java permettant aux développeurs d'utiliser des données relationnelles au travers d'objets et donc de mettre en oeuvre la technique d'ORM.

Cette API est définie dans le package javax.persistance qui fait partie de la plate-forme Java

L'implementation de JPA 2.0 (définie dans Java EE 6) peut se faire avec

  • EclipseLink (anciennement TopLink) - Implémentation de référence - Incluse dans GlassFish 3
  • OpenJPA - Distribué sous licence Apache
  • ...


Weblogic, jusqu'à le version 11gR1 incluse, est un serveur Java EE 5 et ne dispose donc que d'une implémentation de JPA 1.0. Voir liste des serveurs compatibles.
 


Mise en oeuvre avec EclipseLink et MySQL


Dépendances Maven


  • Ajouter la dépendance pour l'API
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>6.0</version>
    <scope>compile</scope>
</dependency>


  • Ajouter la dépendance pour l'implémentation (EclipseLink)
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.5.1</version>
    <scope>provided</scope>
</dependency>


  • Ajouter la dépendance pour le driver (MySQL)
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.29</version>
</dependency>


Cette dépendance doit se placer avant celle de l'API. Si ce n'est pas le cas l'exception suivante risque de se produire
Exception in thread "main" java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in 
class file javax/persistence/Persistence
 


Structure du projet


  • Créer le dossier META-INF dans dans src/main/resources
Eclipse meta inf.png


Unité de persistance


  • Ajouter un fichier persistence.xml dans src/main/resources/META-INF
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <persistence
 4 	version="1.0"
 5 	xmlns="http://java.sun.com/xml/ns/persistence"
 6 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 7 	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
 8 	>
 9 
10 </persistence>


  • Ajouter une unité de persistance dans le fichier persistence.xml
1 <persistence-unit name="tuto">
2     <properties>
3         <property name="javax.persistence.jdbc.driver"   value="com.mysql.jdbc.Driver"/>
4     </properties>
5 </persistence-unit>


Classe de mapping (Entity)


  • Ajouter une classe Student dans src/main/java
 1 package be.java.tuto;
 2 
 3 import javax.persistence.Entity;
 4 import javax.persistence.Id;
 5 
 6 @Entity
 7 public class Student
 8 {
 9 	@Id
10 	private int    id;
11 	private String firstName;
12 	private String lastName;
13         ...
14         getters and setters
15         ...
16 }


{{#if: Les annotation @Entity et @Id sont indispensables.

| {{#if: Les annotation @Entity et @Id sont indispensables. | }}
Les annotation @Entity et @Id sont indispensables.
   | 

}}


Application cliente


  • Obtenir une instance du gestionnaire d'entités
1 EntityManagerFactory emf = Persistence.createEntityManagerFactory("tuto");
2 EntityManager        em  = emf.createEntityManager();
  • Créer une instance de la classe Student
1 Student student = new Student();
2 student.setId(1);
3 student.setFirstName("John");
4 student.setLastName("Smith");
  • Demander au gestionnaire d'entités de persister l'objet
1 em.persist(student);
  • Fermer le gestionnaire d'entités et sa fabrique
1 em.close();
2 emf.close();