Hibernate
I. Introduction
1.1. Généralités
Hibernate est un framework open source appelé ORM (...) ; il permet de "mapper" des objets java à des tables de base de données relationnelles i.e qu'il permet de réaliser la persistance d' objets java; hibernate transcrit des objets de classes Java dans des tables de bases de données, et des types de données Java dans des types de données SQL.
Si deux objets dans une application java sont de couplés, on duplique la clé primaire de la table associée à l'un des deux objets; cette clé devient une clé étrangère dans la table représentant l'autre objet. L'unicité de chaque enregistrement est assurée par la clé primaire de chaque table représentant chaque objet.
1.2. Persistance
Un objet (instance d'une classe) est persistant si l'état des attributs de cet objet est conservé dans les lignes d'une table d'une base de données.
Hibernate donne un aspect partiellement déclaratif à la persistance des informations de la base de données qui sont gérées en mémoire centrale. Il s'adapte à beaucoup de SGBD pour ce qui est des spécificités syntaxiques et sémantiques comme les ordres de création du schéma, les requêtes et les ordres DML (insert - y compris avec l'utilisation d'une séquence Oracle pour produire la valeur de la clef primaire -, update et delete); il traite ces actions en fonction des modifications faites par le programme en mémoire centrale et du dialecte du SGBD sous-jacent.
1.2.1. Persistance sans ORM
Pour réaliser une persistance de données en java sans utiliser un ORM comme Hibernate, on utilise l'API JDBC(Application Programming Interface); cet API permet l'accès aux données transcrites dans des tables de bases de données (SGBD) relationnelles; si on utilise JDBC on suit en général les différentes étapes suivantes :
- Utiliser la classe "java.sql.Connection" pour se connecter à la base de données. Pour avoir la connexion à la base de données on se sert soit de "java.sql.DriverManager" ou de "javax.sql.DataSource"; pour plus d'efficacité on utilise javax.sql.DataSource ( voir exemple )
- Utiliser "java.sq.Statement" depuis la connexion,
- Exécuter du code SQL via les méthodes executeUpdate() ou executeQuery(); Dans le deuxième cas un objet "java.sql.ResultSet " est retourné.
- En cas d'interrogation de la base de données, il y a une lecture du résultat depuis l'objet resultSet avec la possibilité de faire des itérations sur celui-ci.
- Fermer resultSet si nécessaire
- Fermer Statement
- Fermer la connexion
et ceci s'illustre par le petit exemple suivant:
Exemples
........ public static String getQuoteString(DataSource dataSource){ Connection con = null; try{ con = dataSource.getConnection(); String str = con.getMetaData().getIdentifierQuoteString(); return " ".equals(str) ? null : str; }catch(SQLException ex){ throw new RuntimeException(ex); }finally{ try{ if(con!=null) con.close(); }catch(SQLException ignore){ ignore.printStackTrace(); } } }
........................ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException;
import java.util.Properties; public class Main { public static Connection getConnection(String dbURL, String user, String password) throws SQLException, ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); Properties props = new Properties(); props.put("user", user); props.put("password", password); props.put("autoReconnect", "true"); return DriverManager.getConnection(dbURL, props); } public static void main(String[] args) { Connection conn = null; try { conn = getConnection("jdbc:mysql://localhost/empDB", "root", "pass"); } catch (Exception ex) { System.out.println("SQLException: " + ex.getMessage()); } } }
1.2.2. Persistance avec l'ORM Hibernate
Si on réalise la persistance des données en se servant d'une ORM comme Hibernate, on délègue au développeur la responsabilité de coder la persistance des objets.
Voici ce que nous pourrions écrire à la place du bout de programme ci-dessus si nous implémentions une couche d'accès aux données :
Exemple
.........
On voit bien qu'une table peut être facilement encapsulée par une classe dans une couche d'accès aux données.
( à suivre....)
II. Principe du mappage objet-relationnel
1. Généralités
Le principe du mappage objet-relationnel (ORM ou object-relational mapping) consiste à déléguer l'accès aux données à des outils ou frameworks externes comme on l'a dit ci-dessus. Son avantage est de proposer une vue orientée objet d'une structure de données relationnelle (lignes et colonnes).
Pour charger, stocker et utiliser des objets d'une classe persistante, Hibernate s'appuie sur des fichiers de mappage, un fichier pour chaque objet persistant. Ce fichier de mappage dont l'extension est ".hbm.xml", indique à Hibernate à quelle table dans la base de données il doit accéder, et quelles colonnes de celle-ci il devra utiliser.
Hibernate ne chargera pas le fichier "DTD" de mappage à partir du web, mais regardera d'abord dans le classpath de l'application. Le fichier "DTD" est inclus dans "hibernate3.jar" ainsi que dans le répertoire src de la distribution Hibernate. Pour utiliser Hibernate on utilise soit :
- un fichier XML contenant la mapping de la classe,
- des annotations directement incluses dans le code source de la classe Java
1.2. Fichier contenant le mapping d'une classe
Une classe appelée NomClass d'une application java est dite mappée si un fichier de configuration "NomClass.hbm.xml" lui est associé. Ce fichier XML, décrit l'aspect relationnel des objets instances de cette classe, les associations que ces objets entretiennent avec d'autres classes mappées .
Le code Java d'une classe mappée ressemble à un Java Bean; en effet une classe mappée doit disposer de méthodes getter/setter associés à chaque propriété de la classe; elle doit aussi proposer un constructeur sans paramètres visible dans le paquetage.
Si la Clé primaire est composée de plus d'une colonne, le programmeur décrit cette clé par une nouvelle classe. La structure générale d'un fichier de mappage est la suivante:
1.2.1. Exemple de fichier d'extension ".hbm.xml"
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping> [...] </hibernate-mapping>
Entre les deux balises <hibernate-mapping> et </hibernate-mapping>, on inclut des éléments; l'un des plus importants d'entre eux est l'élément class. Un objet Java est persistant, c'est à dire a sa place dans une table de la base de données gérée par Hibernate,s'il est instance d'une classe Java mappée. Le mappage d'une classe permet, entre autre, de savoir comment la table correspondante devra être implantée dans le SGBD utilisée par l'application.
Toutes les classes d'entités persistantes (il pourrait y avoir des classes dépendantes qui ne sont pas des entités mère) ont besoin d'un mapping vers une table de la base de données relationnelles.
( à suivre....)
(à suivre)..