2.3 Hibernate ORM - dosseggegw1/AMT_projet Wiki

Hibernate ?

Un ORM (Object-Relational Mapping) est un outil qui permet de convertir des bases de données relationnelles en langage de programmation orientée objets (-> Java).

Donc la base de données et liée directement au code Java à l'aide d'un driver (JTA, JDBC ou JNDI).

Fichiers du code

Liaison avec MySQL Database

Afin de pouvoir faire la connexion avec la base de donnée, il est nécessaire de préciser toute la configuration dans un fichier, hibernate.cfg.xml. Il y a plusieurs balises à utiliser dans le fichier.

Voilà un exemple de configuration:

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>

     <!-- Propriété de la base de données (ici on précise qu'on utilise MySQL) -->
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
      
      <!-- Propriété du driver pour la connexion -->
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
      
      <!-- Propriété de l'URL de la connexion de la bdd -->
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost:3306/test
      </property>

      <!-- Propriété de l'utilisateur de la bdd -->      
      <property name = "hibernate.connection.username">
         root
      </property>

      <!-- Propriété du mot de passe de la bdd -->      
      <property name = "hibernate.connection.password">
         root
      </property>
      
      <!-- List of XML mapping files -->
      <mapping class="com.org.model.Employee"/>
      
   </session-factory>
</hibernate-configuration>

Méthode 1

Mapping d'une table

On voit que dans le fichier hibernate.cfg.xml, on précise nos classes de mapping. Cette classe de mapping sert à faire l'entre-deux entre la table de la base de données et la classe POJO (classe modèle). On va donc littéralement traduire la table de la base de données vers le fichier de la classe XML. Exemple de table:

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Fichier de mapping:

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Classe POJO

Une classe POJO (Plain Old Java Object) est une classe modèle d'une table de la base de données.

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Méthode 2 (préférée !!)

Cette méthode permet de supprimer le fichier XML de mapping et d'avoir seulement une classe modèle avec des annotations en plus. On utilise l'API JPA (Java Persistence API) qui permet d'ajouter des fonctions dans la classe POJO. Pour les annotations et comment les utiliser, voir la page JPA Annotations.

Il ne faut pas oublier d'ajouter la balise de mapping dans le fichier hibernate.cfg.xml.

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  

   public Employee() {}
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Requêtes CRUD

Afin d'effectuer des requêtes vers la base de données, il faut premièrement s'y connecter. Pour ce faire, il y a une classe HibUtil qui se trouve dans le package util du projet principal.

Afin de commencer une session (connexion avec des requêtes), on peut écrire cette ligne:

Session session = HibUtil.getSessionFactory().getCurrentSession();

Pour fermer la session:

HibUtil.getSessionFactory().close();

/!\ ne pas appeler cette dernière méthode pour l'instant, sinon la session est fermée définitivement.

CREATE

session = HibUtil.getSessionFactory().getCurrentSession();
// Pour commencer la requête
session.beginTransaction();
// Création d'un nouvel employé
Employee employee = new Employee();
employee.setFirstName(fname);
employee.setLastName(lname);
employee.setSalary(salary);
// Sauvegarde du nouvel objet
employeeID = (Integer)session.save(employee);
// Commit des requêtes
session.getTransaction().commit();
session.close();

READ

session = HibUtil.getSessionFactory().getCurrentSession();
// Pour commencer la requête
session.beginTransaction();
List employees = session.createQuery("FROM Employee").list(); 
// Affichage de chaque employé
for (Iterator iterator = employees.iterator(); iterator.hasNext();){
   Employee employee = (Employee) iterator.next(); 
   System.out.print("First Name: " + employee.getFirstName()); 
   System.out.print("  Last Name: " + employee.getLastName()); 
   System.out.println("  Salary: " + employee.getSalary()); 
}
// Commit des requêtes
session.getTransaction().commit();
session.close();

UPDATE

session = HibUtil.getSessionFactory().getCurrentSession();
// Pour commencer la requête
session.beginTransaction();
// On récupère l'employé avec son ID qu'on a reçu lors de la création d'un objet (appel à la méthode save)
Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
employee.setSalary( salary );
session.update(employee); 
// Commit des requêtes
session.getTransaction().commit();
session.close();

DELETE

session = HibUtil.getSessionFactory().getCurrentSession();
// Pour commencer la requête
session.beginTransaction();
// On récupère l'employé avec son ID qu'on a reçu lors de la création d'un objet (appel à la méthode save)
Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
session.delete(employee); 
// Commit des requêtes
session.getTransaction().commit();
session.close();

Requêtes Query

Une autre possibilité d'effectuer des requêtes c'est avec Query. On ajoute une requêtes MySQL dans une String et on la crée avec Query. Par la suite, une liste nous est retournée:

String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

sources