Développons en Java avec Eclipse 0.80.1 | |
Copyright (C) 2003-2008 Jean-Michel DOUDOUX | (date de publication : 26/12/2008) |
|
Hibernate est un projet open source visant à proposer un outil de mapping entre les objets et des données stockées dans une base de données relationnelle. Ce projet ne repose sur aucun standard mais il est très populaire notamment à cause de ses bonnes performances et de son ouverture avec de nombreuses bases de données.
Le site officiel http://www.hibernate.org contient beaucoup d'informations sur l'outil et propose de le télécharger ainsi que sa documentation.
Le plug-in Hibernate Synchronizer permet la génération de code utilisant le framework Hibernate. Il permet aussi de re-générer ce code lorsqu'un fichier de mapping est modifié. |
Le site du plug-in est à l'url : http://hibernatesynch.sourceforge.net/
Version utilisée dans cette section |
|
Eclipse |
3.0.1 |
J2SE |
1.4.2_03 |
Hibernate Synchronizer |
2.3.1. |
Le plus simple est d'utiliser la fonctionnalité de mise à jour proposée par l'option "Rechercher et installer" du menu "Aide". Cliquez sur le bouton "Rechercher les nouveaux dispositifs à installer" sur le bouton "Nouveau site distant", saisissez les informations ci dessous et suivez les instructions pour réaliser le téléchargement et l'installation.
La base de données utilisées dans cette section contient trois tables :
Exemple : le DDL de la base de données |
drop table `grppers`;
drop table `groupes`;
drop table `personnes`;
#
# Structure for the `groupes` table :
#
CREATE TABLE `groupes` (
`idgroupe` int(4) NOT NULL auto_increment,
`nomgroupe` varchar(50) default NULL,
`commentairegroupe` varchar(150) default NULL,
PRIMARY KEY (`idgroupe`),
UNIQUE KEY `idgroupe` (`idgroupe`)
) TYPE=InnoDB;
#
# Structure for the `personnes` table :
#
CREATE TABLE `personnes` (
`idpersonne` int(11) NOT NULL auto_increment,
`nompersonne` varchar(50) default NULL,
`prenompersonne` varchar(50) default NULL,
`datenaisspersonne` datetime default NULL,
`coeffpersonne` int(11) default NULL,
PRIMARY KEY (`idpersonne`),
UNIQUE KEY `idpersonne` (`idpersonne`)
) TYPE=InnoDB;
#
# Structure for the `grppers` table :
#
CREATE TABLE `grppers` (
`idgrppers` int(11) NOT NULL auto_increment,
`idgroupe` int(11) default NULL,
`idpersonne` int(11) default NULL,
PRIMARY KEY (`idgrppers`),
UNIQUE KEY `idgrppers` (`idgrppers`),
KEY `idgroupe` (`idgroupe`),
KEY `idpersonne` (`idpersonne`),
CONSTRAINT `0_48` FOREIGN KEY (`idpersonne`) REFERENCES `personnes` (`idpersonne`),
CONSTRAINT `0_45` FOREIGN KEY (`idgroupe`) REFERENCES `groupes` (`idgroupe`)
) TYPE=InnoDB;
INSERT INTO `groupes` (`idgroupe`, `nomgroupe`, `commentairegroupe`) VALUES
(1,'groupe 1',NULL),
(2,'groupe 2',NULL);
INSERT INTO `grppers` (`idgrppers`, `idgroupe`, `idpersonne`) VALUES
(1,1,1),
(2,2,2),
(3,2,3),
(4,1,4),
(5,1,5);
INSERT INTO `personnes` (`idpersonne`, `nompersonne`, `prenompersonne`,
`datenaisspersonne`, `coeffpersonne`) VALUES
(1,'nom1','prenom1','1967-01-06',123),
(2,'nom2','prenom2','1973-08-11',34),
(3,'nom3','prenom3','1956-04-28',145),
(4,'nom4','prenom4','1980-12-02',23),
(5,'nom5','prenom5','1966-10-13',119); |
Créer un nouveau projet dont les sources et les binaires sont séparés et ajouter les fichiers mm.mysql-2.0.14-bin.jar et hibernate2.jar dans les bibliothèques.
Il est aussi obligatoire d'ajouter toutes les bibliothèques nécessaires à Hibernate lors de son exécution.
Il faut ensuite créer une entité de type « Hibernate / Hibernate Mapping File » dans le répertoire src du projet.
Cliquez sur le bouton « Suivant ». La page suivante permet de saisir les informations sur la base de données et sa connexion.
Cliquez sur le bouton « Browse » en face de « Driver ».
Sélectionnez la classe org.gjt.mm.mysql.Driver et cliquez sur le bouton « OK ».
Il faut ensuite saisir les informations concernant la connexion à la base de données et cliquer sur le bouton « Refresh ».
Si les paramètres concernant la connexion sont corrects alors la liste des tables est affichée. Il suffit alors de sélectionner la ou les tables désirées.
Enfin, il faut saisir le nom du package qui va contenir les fichiers générés.
Cliquez sur le bouton « Fin ». Trois fichiers sont générés : Groupes.hbm, Grppers.hbm et Personnes.hbm
Exemple : le fichier Personnes.hbm |
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping package="com.jmd.test.hibernate">
<class name="Personnes" table="personnes">
<id
column="idpersonne"
name="Idpersonne"
type="integer"
>
<generator class="vm" />
</id>
<property
column="datenaisspersonne"
length="19"
name="Datenaisspersonne"
not-null="false"
type="timestamp"
/>
<property
column="prenompersonne"
length="50"
name="Prenompersonne"
not-null="false"
type="string"
/>
<property
column="coeffpersonne"
length="11"
name="Coeffpersonne"
not-null="false"
type="integer"
/>
<property
column="nompersonne"
length="50"
name="Nompersonne"
not-null="false"
type="string"
/>
</class>
</hibernate-mapping> |
Exemple : le fichier Groupes.hbm |
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping package="com.jmd.test.hibernate">
<class name="Groupes" table="groupes">
<id
column="idgroupe"
name="Idgroupe"
type="integer"
>
<generator class="vm" />
</id>
<property
column="nomgroupe"
length="50"
name="Nomgroupe"
not-null="false"
type="string"
/>
<property
column="commentairegroupe"
length="150"
name="Commentairegroupe"
not-null="false"
type="string"
/>
</class>
</hibernate-mapping> |
Exemple : le fichier Grppers.hbm |
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping package="com.jmd.test.hibernate">
<class name="Grppers" table="grppers">
<id
column="idgrppers"
name="Idgrppers"
type="integer"
>
<generator class="vm" />
</id>
<many-to-one
class="Groupes"
name="Idgroupe"
not-null="true"
>
<column name="idgroupe" />
</many-to-one>
<many-to-one
class="Personnes"
name="Idpersonne"
not-null="true"
>
<column name="idpersonne" />
</many-to-one>
</class>
</hibernate-mapping> |
La génération des classes correspondantes pour chaque fichier .hbm peut être demandée de deux façons :
Cette génération va créer pour chaque fichier .hbm plusieurs classes.
Il faut créer une nouvelle entité de type « Hibernate / Hibernate Configuration File » dans le répertoire src. Une boite de dialogue permet de saisir les informations qui seront insérées dans le fichier de configuration d'Hibernate.
Une fois les informations saisies, cliquez sur le bouton « Fin »
Il faut rajouter dans ce fichier tous les fichiers de mapping qui seront utilisés.
Exemple : |
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory >
<!-- local connection properties -->
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<!-- property name="hibernate.connection.pool_size"></property -->
<!-- dialect for MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.use_outer_join">true</property>
<mapping resource="Personnes.hbm"/>
<mapping resource="Grppers.hbm"/>
<mapping resource="Groupes.hbm"/>
</session-factory>
</hibernate-configuration> |
Les différentes classes qui vont mettre en oeuvre les classes générées vont utiliser une classe utilitaire proposée dans la documentation de Hibernate pour configurer et obtenir une session.
Exemple : |
package com.jmd.test.hibernate;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Exception building SessionFactory: "
+ ex.getMessage(), ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
} |
Le premier exemple va simplement afficher le nom de toutes les personnes.
Exemple : |
import java.util.*;
import net.sf.hibernate.*;
import com.jmd.test.hibernate.*;
public class Test1 {
public static void main(String[] args) {
try {
Session session = HibernateUtil.currentSession();
List list = session.find("from Personnes ");
Iterator it = list.iterator();
while(it.hasNext())
{
Personnes personne = (Personnes)it.next();
System.out.println(personne.getNompersonne());
}
HibernateUtil.closeSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
} |
Exemple : |
Résultat :
nom1
nom2
nom3
nom4
nom5 |
Voici le même exemple utilisant les classes générés mettant en oeuvre le motif de conception DAO.
Exemple : |
import java.util.Iterator;
import java.util.List;
import net.sf.hibernate.HibernateException;
import com.jmd.test.hibernate.Personnes;
import com.jmd.test.hibernate.dao.PersonnesDAO;
import com.jmd.test.hibernate.dao._RootDAO;
public class Test1DAO {
public static void main(String[] args) {
try {
_RootDAO.initialize();
PersonnesDAO dao = new PersonnesDAO();
List liste = dao.findAll();
Iterator it = liste.iterator();
while (it.hasNext()) {
Personnes personne = (Personnes) it.next();
System.out.println(personne.getNompersonne());
}
} catch (HibernateException e) {
e.printStackTrace();
}
}
} |
Le second exemple va retrouver un groupe, créer une nouvelle personne et l'ajouter au groupe trouvé.
Exemple : |
import java.util.*;
import net.sf.hibernate.*;
import com.jmd.test.hibernate.*;
public class Test2 {
public static void main(String[] args) {
try {
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Personnes personne = new Personnes();
personne.setNompersonne("nom6");
personne.setPrenompersonne("prenom6");
personne.setCoeffpersonne(new Integer(46));
personne.setDatenaisspersonne(new Date());
session.save(personne);
Groupes groupe = (Groupes) session.load(Groupes.class, new Integer(1));
Grppers grppres = new Grppers();
grppres.setIdpersonne(personne);
grppres.setIdgroupe(groupe);
session.save(grppres);
tx.commit();
HibernateUtil.closeSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
} |
Voici le même exemple utilisant les classes générés mettant en oeuvre le motif de conception DAO.
Exemple : |
import java.util.*;
import net.sf.hibernate.*;
import com.jmd.test.hibernate.*;
import com.jmd.test.hibernate.dao.*;
public class Test2DAO {
public static void main(String[] args) {
try {
_RootDAO.initialize();
Session session = _RootDAO.createSession();
Transaction tx = session.beginTransaction();
Personnes personne = new Personnes();
personne.setNompersonne("nom7");
personne.setPrenompersonne("prenom7");
personne.setCoeffpersonne(new Integer(46));
personne.setDatenaisspersonne(new Date());
PersonnesDAO personnesDAO = new PersonnesDAO();
personnesDAO.save(personne, session);
GroupesDAO groupesDAO = new GroupesDAO();
Groupes groupe = groupesDAO.load(new Integer(1),session);
Grppers grppres = new Grppers();
grppres.setIdpersonne(personne);
grppres.setIdgroupe(groupe);
GrppersDAO grppresDAO = new GrppersDAO();
grppresDAO.save(grppres, session);
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
} |
Si une des tables à traiter ne contient que des données de références (un identifiant et une valeur), alors Hibernate Synchronize propose de créer une classe particulière qui va encapsuler les données non pas de façon dynamique via un accès à la table mais de façon statique.
Dans ce cas, une boîte de dialogue demande si la classe générée doit l'être de façon statique (création comme une énumération)
Exemple : la table groupes ne possède que deux champs (idgroupe et nomgroupe)
En cliquant sur le bouton « Oui » la classe suivante est générée :
Exemple : |
package com.jmd.test.hibernate;
import java.io.Serializable;
import net.sf.hibernate.PersistentEnum;
/**
* This class has been automatically generated by Hibernate Synchronizer.
* For more information or documentation, visit The Hibernate Synchronizer page
* at http://www.binamics.com/hibernatesync or contact Joe Hudson at joe@binamics.com.
*/
public class Groupes implements Serializable, PersistentEnum {
public static final Groupes GROUPE_2 = new Groupes(2);
public static final Groupes GROUPE_1 = new Groupes(1);
private final int code;
protected Groupes(int code) {
this.code = code;
}
public int toInt() { return code; }
public static Groupes fromInt(int code) {
switch (code) {
case 2: return GROUPE_2;
case 1: return GROUPE_1;
default: throw new RuntimeException("Unknown value: " + code);
}
}
public String toString () {
switch (code) {
case 2: return "groupe 2";
case 1: return "groupe 1";
default: return "Unknown value";
}
}
} |
|