Dans la plupart de mes projets nous avons utilisé Hibernate. Hibernate offre une couche d'abstraction entre le monde Objet en Java et les bases de données relationnelles. Il permet de faire ainsi le lien entre des classes Java POJO (classes standard Plain Old Java Object) et du SQL. Il utilise quelques fichiers XML pour la configuration et des annotations Java pour faire la correspondance avec les tables SQL. Je vais décrire dans ce billet à travers un exemple simple comment utiliser le plugin Eclipse pour générer automatiquement les classes Java à partir d'une base de données existante.
J'ai utilisé :
- Spring Tool Suite 3.3.0 basé sur Eclipse Kepler
- Jboss Tools pour le plugin Hibernate Eclipse
- Les libraries Hibernate3
- Java 1.6 & 1.7
- Java DB (ou Apache Derby, c'est la même application)
Tout d'abord, installez le plugin Hibernate dans Eclipse (Help->Install New Software).
Création de la base de données
Sous Java DB, démarrez la base de donnée en mode serveur "startNetworkServer.bat".
Lancez l'utilitaire "ij.bat" fourni pour créer une base de données.
connect 'jdbc:derby://localhost:1527/test;user=linus;password=ChangeMe;create=true';
Un répertoire nommé test sera créé et contiendra les données de la base.Vous pourrez vous reconnecter ultérieurement à la base à l'aide de la commande suivante.
connect 'jdbc:derby://localhost:1527/test;user=linus;password=ChangeMe';
Toujours sous "ij", créez une base de données "dbnote".
create table DBNote (
id int generated by default as identity not null,
SID varchar(50),
date date,
title varchar(100),
marked int,
content varchar(4096));
Executez la commande "commit;" pour être certain que les données sont bien écrites en base et vérifier que la table a bien été créée avec la commande "describe dbnote;".
ij> commit;
ij> describe dbnote;
COLUMN_NAME |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
------------------------------------------------------------------------------
ID |INTEGER |0 |10 |10 |GENERATED&|NULL |NO
SID |VARCHAR |NULL|NULL|50 |NULL |100 |YES
DATE |DATE |0 |10 |10 |NULL |NULL |YES
TITLE |VARCHAR |NULL|NULL|100 |NULL |200 |YES
MARKED |INTEGER |0 |10 |10 |NULL |NULL |YES
CONTENT |VARCHAR |NULL|NULL|4096 |NULL |8192 |YES
6 lignes sΘlectionnΘes
ij>
Création du projet sous Eclipse
Créez un nouveau projet TestHibernate.Ajoutez un répertoire "lib" qui contiendra les librairies Java nécessaires à Hibernate ainsi que la librairie pour l'accès à la base de données.
Les librairies suivantes sont obligatoires pour hibernate :
- hibernate3.jar
- antlr-2.7.6.jar
- commons-collections-3.1.jar
- dom4j-1.6.1.jar
- javassist-3.1.2.0.GA.jar
- jta-1.1.jar
- slf4j.api-1.6.1.jar
La librairie hibernate-jpa-2.0-api-1.0.1.Final.jar est nécessaire qui si vous souhaitez utiliser de annotations. Vous avez le choix entre les utiliser ou utiliser le fichier "dbnote.hbm.xml" qui contient les informations de mapping. Utilisez de préférence les annotations, ce qui fera un fichier de moins à gérer.
La librairie cp30-0.9.1.jar est utilisée pour gérer un pool de connexions à la base de données. Les ouvertures de connexions sont assez couteuses en temps. Il est préférable de créer quelques connexions dès le démarrage de l'application et d'en garder quelques unes actives. Cela n'empêche pas les risques de déconnexion, mais cela vous assurera que vous aurez une connexion valide lorsque vous exécuterez votre requête.
1. Première étape, création du fichier de configuration qui permettra de se connecter à la base de données et d'indiquer le "dialect" à utiliser pour la conversion entre le Java et le SQL propriétaire de la base de données. Si vous souhaitez utiliser des annotations, sélectionnez "Annotation JDK 1.5+". Donnez un nom à la configuration et cliquez sur New pour créer la connexion à la base.
Pour Java DB, sélectionnez Derby.
Entrez les paramètres de connexion à la base :
- database : test (c'est la base qui a été créée dans la section précédente)
- host : localhost (car la base se trouve sur le même PC)
- port : 1527 (c'est le port par défaut de Derby, mais il peut être modifié)
- username : linus (indiqué à la création de la base)
- password : ChangeMe (indiqué à la création de la base. Attention, si vous cochez "Save Password", le mot de passe sera sauvegardé en clair dans le fichier de configuration. Il faut donc éviter de le faire si votre machine est exposée sur Internet).
Cliquez sur "Finish". Dans l'onglet "Options", sélectionnez le "Dialect" Derby.
Si vous avez oublié des options ou si vous souhaitez modifier le nom d'une configuration, vous pouvez ré-éditer la configuration à tout moment en allant dans la perspective "Hibernate". Vous y trouverez également la base configurée ainsi que les tables accessibles.
La configuration est stockée dans un fichier hibernate.cfg.xml qui peut également être édité à la main.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="">
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
<property name="hibernate.connection.password">ChangeMe</property>
<property name="hibernate.connection.url">jdbc:derby://localhost:1527/test;create=true</property>
<property name="hibernate.connection.username">linus</property>
<property name="hibernate.default_schema">LINUS</property>
<property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
<mapping class="com.hibernate.test.Dbnote"/>
</session-factory>
</hibernate-configuration>
2. Seconde étape, définition du fichier de Reverse Engineering qui permettra de générer les classes Java. Sélectionnez le menu "Run", puis "Hibernate Code Generation" pour créer une nouvelle configuration.
Dans l'onglet "Main", indiquez dans quel répertoire vous souhaitez sauvegarder la configuration du Reverse Engineering.
Indiquez dans quel répertoire vous souhaitez stocker le fichier. Cela peut être à la racine du projet ou dans le répertoire source. Cela n'a pas beaucoup d'importance. Ce fichier n'est pas utilisé pour l'exécution.
Sélectionnez les classes que vous souhaitez utiliser et excluez les classes ou les bases de données que vous ne souhaitez pas utiliser. Sur de très grosses bases de plusieurs centaines ou milliers de tables, cette étape est nécessaire car elle permet d'améliorer de manière assez significative le temps d'ouverture de la base.
Dans l'onglet "Exporters", sélectionnez "Use Java 5 syntax" et "Generate EJB3 annotations". C'est cette dernière option qui générera les annotations dans le code Java. Vous pouvez ensuite générer le fichier "Hibernate XML mappings", mais ce dernier n'est pas nécessaire si vous utilisez les annotations. Vous pouvez également choisir de générer le fichier XML et d'avoir une classe Java standard sans annotation. Dans la mesure du possible, essayez d'utiliser pleinement les possibilités offertes par l'outil de Reverse Engineering, ce qui vous permettra de régénérer les classes automatiquement et essayez de ne pas modifier les classes générer. J'ai choisi de générer les classes directement dans le répertoire "src", mais vous pouvez utiliser un répertoire séparé pour éviter d'écraser vos éventuelles modifications manuelles.
Dans l'onglet "Refresh", sélectionnez "Refresh Resources upon completion" et "The project containing the selected resource" pour éviter que tous les projets du Workspace ne soient recompilés.
Cliquez sur close. On rajoutera des propriétés supplémentaires sur le fichier de Reverse Engineering.
3. Mettez à jour le projet afin de rajouter le support pour Hibernate. Cliquez sur "Details" pour sélectionner le fichier de configuration à sélectionner.
Selectionnez "Get values from connection" pour remplir automatiquement tous les champs.
4. Editez le fichier "hibernate.reveng.xml" depuis la perspective "Java".
Ajoutez la table DBNOTE en cliquant sur le bouton "Add". Une fois toutes les colonnes de la table ajoutées, cliquez sur "Add primary key" pour indiquer la clé primaire. Selectionnez "Add generator" et "Add column".
Pour la valeur de "Id Generator details", saissez "native", ce qui permettra d'utiliser l'auto-incrémentation native de Derby. Pour Oracle, il faudra indiquer la séquence à utiliser avec "Add parameter".
Pour la valeur de "Column details", saisisser "ID" qui est la clé primaire.
Supprimez la colonne "ID" de la liste des colonnes affichées.
Vous pouvez également éditer le fichier XML directement. C'est plus rapide et plus simple pour rajouter la Primary Key.
Dans le menu "Run", "Hibernate code generation", exécutez la configuration de reverse Engineering. Cela génèrera une classe Java avec des annotations.
package com.hibernate.test;
// Generated 19 sept. 2013 11:17:43 by Hibernate Tools 4.0.0
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Dbnote generated by hbm2java
*/
@Entity
@Table(name = "DBNOTE")
public class Dbnote implements java.io.Serializable {
private Integer id;
private String sid;
private Date date;
private String title;
private Integer marked;
private String content;
public Dbnote() {
}
public Dbnote(String sid, Date date, String title, Integer marked,
String content) {
this.sid = sid;
this.date = date;
this.title = title;
this.marked = marked;
this.content = content;
}
@Id
@GeneratedValue
@Column(name = "ID", nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "SID", length = 50)
public String getSid() {
return this.sid;
}
public void setSid(String sid) {
this.sid = sid;
}
@Temporal(TemporalType.DATE)
@Column(name = "DATE", length = 10)
public Date getDate() {
return this.date;
}
public void setDate(Date date) {
this.date = date;
}
@Column(name = "TITLE", length = 100)
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
@Column(name = "MARKED")
public Integer getMarked() {
return this.marked;
}
public void setMarked(Integer marked) {
this.marked = marked;
}
@Column(name = "CONTENT", length = 4096)
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
}
5. Test de la classe Hibernate générée.
Créez une classe dans le projet pour tester la classe générée. Nous allons tester l'insertion d'une donnée dans la base, ainsi que la lecture de la donnée en indiquant sont ID. Faites d'abord une requête en base afin de vous assurer que l'ID existe bien.
Les classes à mapper sont également décrites dans le fichier "hibernate.cfg.xml". Vous pouvez en rajouter en éditant ce fichier.
Le fichier de configuration contenant
les informations de connexions à la base est lu avec la commande
"config.configure(configFile)". Par défaut le fichier de configuration doit être dans le répertoire "bin", mais vous pouvez le mettre à un autre endroit.
La commande "config.buildSessionFactory" permet de retrouver toutes les classes, y compris celles qui contiennent des annotations. Vous pouvez également choisir d'utiliser les fichiers "hbm.xml" si vous le souhaitez.
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import com.hibernate.test.Dbnote;
import java.io.File;
import java.util.Date;
public class TestHibernate {
public static void main(String args[]) throws Exception {
Configuration config = new Configuration();
File configFile = new File("hibernate.cfg.xml");
config.configure(configFile);
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// Insert one note in database
Dbnote note = new Dbnote("123", new Date(), "TEST", 0, "");
session.save(note);
session.flush();
tx.commit();
// Reload the note with ID 1
Dbnote instance = (Dbnote)session.load(Dbnote.class, 1);
System.out.println(instance.getTitle());
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
sessionFactory.close();
System.exit(0);
}
}
Le projet complet peut être téléchargé ici.
Le nombre d'étapes est relativement important, mais la plupart d'entre elles ne sont exécutées qu'une seule fois.
N'hésitez pas à laisser a poser des questions si vous rencontrez des problèmes.
Commentaires
Enregistrer un commentaire