Hibernate - Introduzione

hibernate

Salve a tutti,
con questo articolo spiegheremo cosa è Hibernate e come è possibile usare le sue potenzialità.

Introduzione a Hibernate

Hibernate ORM (conosciuto anche con H8) è una piattaforma sviluppata, a partire dal 2001, da Gavin King e dai suoi colleghi della Cirrus Technologies per applicazioni Java. Essa fornisce, attraverso il proprio framework, un servizio di Object relational mapping (ORM). In generale l'ORM è una tecnica di programmazione che permette di "mappare" oggetti (di un qualsiasi linguaggio Object-Oriented) su un Database Relazionale. Questa operazione non è banale: un oggetto è rappresentabile mediante un grafo interconnesso con altri oggetti, mentre gli RDBMS (Relational Database Management System) hanno una rappresentazione dei dati in forma tabellare; è facile capire che il salvataggio o la modifica di questi "grafi" all’interno delle tabelle è una operazione piuttosto complessa.
Attraverso l'utilizzo di un framework come Hibernate lo sviluppatore non dovrà più preoccuparsi di gestire la persistenza dei dati e di conseguenza le procedure per le operazioni CRUD dei database (Create, Read, Update, Delete) saranno molto più semplici.
Hibernate fornisce il mapping tra le classi Java e le tabelle di un database relazione e attraverso di esso viene gestito il salvataggio e la lettura dei dati.
Altre caratteristiche sono:

  • non stravolge il paradigma Object-Oriented di Java e di conseguenza permette l’uso dell'eredarietà, del polimorfismo, le associazioni, le collections etc etc;
  • è altamente customizzabile and estendibile;
  • è portabile in tutti i database di tipo SQL (Oracle, PostgreSQL,  SQL Server, MySQL solo per citare i più utilizzati);
  • fornisce una persistenza trasparente per POJO (Plain Old Java Object);
  • fin dall'inizio è stato progettato per lavorare in applicazioni basate su cluster di server e per fornire un’architettura altamente scalabile.

Architettura di Hibernate

Mapping

Il mapping tra le classi Java e le tabelle del database è fornito da un file XML o attraverso la Java Annotations. Attraverso questo mapping è possibile definire anche la molteplicità e le subrelazioni. Non esiste una soluzione migliore dell'altra e spesso la scelta ricade su quella che il programmatore ritiene più facile da manutenere.

Mapping con file xml

Nel file xml viene indicata la classe java da utilizzare e la mappatura, indicando anche eventuali sequence e rapporti esistenti tra gli oggetti.
Supponiamo di voler creare un database con dei dati riguardanti dei libri e delle biblioteche locali.
In tal caso una mappatura potrebbe essere come quella qui indicata:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-cascade="save-update">
    <!-- Book -->
    <class name="com.ventus85.test.hibernate.Book" table="Book">
        <id name="id" type="int" unsaved-value="-1">
            <generator class="sequence">
                <param name="sequence">book_gen
                </param>
            </generator>
        </id>
        <property name="title"/>
        <property name="author"/>
        <property name="editor"/>
    </class>
    <!-- Library -->
    <class name="com.ventus85.test.hibernate.Library" table="Library">
        <id name="id" type="int" unsaved-value="-1">
            <generator class="sequence">
                <param name="sequence">library_gen
                </param>
            </generator>
        </id>
        <property name="iccu"/>
        <property name="name"/>
        <property name="address"/>
        <property name="city"/>
        <property name="zipCode"/>
        <property name="publicLibrary"/>
    </class>
</hibernate-mapping>

Leggendo questo file possiamo capire facilmente quali siano le colonne delle nostre due tabelle del database (Book e Library) e quali sono le classi java con gli attributi mappati. Non è necessario indicare, nel file xml, il tipo di dati utilizzati, mentre possiamo indicare quale è la colonna che sarà utilizzata come identificativo e l'eventuale sequence.
In generale il file di mapping contiene i seguenti elementi:

  • hibernate-mapping: è l'elemento principale (root) che contiene la mappatura di tutte le classi;
  • class: elemento utilizzato per specificare la mappatura tra la classe Java e la tabella del database. Contiene due elementi: "name" che contiene il nome della classe java con path e "table" che contiene il nome della tabella;
  • meta: elemento opzionale, contiene la descrizione della classe;
  • id: elemento che indica quale attributo della classe è la chiave primaria della tabell;.
  • generator: elemento che indica come viene generata automaticamente la chiave primaria, per esempio tramite una sequence;
  • property: elemento per indicare la mappatura tra attributo della classe Java e colonna della tabella.

Ci sono poi altri elementi che vengono utilizzati, per esempio per indicare le relazioni uno-a-molti o molti-a-molti e li vedremo in un altro articolo.

Mapping con annotations

L'alternativa al mapping consiste nell'utilizzare le JPA annotations. In questo modo si specifica il mapping direttamente all’interno delle stesse classi da persistere.
Riprendendo l'esempio dei libri e delle biblioteche la classe java Book con le annotations potrebbe essere come la seguente.

@Entity
@Table(name = "BOOK")
public class Book {

  public Book(){
  }

  @Id  
  @Column(name = "ID")
  String id;
 
  @Column(name = "AUTORE")
  String autore;
     
  @Column(name = "TITOLO")
  String titolo;
 
  // metodi get e set
  // altri metodi
 } 

Anche in questo caso è facile capire come funziona il mapping.
Le principali annotations da utilizzare sono le seguenti:

  • Entity: per indicare che la classe deve essere trattate come un bean (quindi dovrà avere un costruttore senza argomenti con una visibilità almeno "protected");
  • Table: per specificare le caratteristiche della tabella;
  • Column: per indicare i dettagli della colonna, quali il nome, se deve contenere valori unici, valori null etc etc;
  • Id: per indicare la chiave primaria.

Cosa serve

Ovviamente per utilizzare Hibernate non basta creare le classi Java e i file xml, ma bisogna utilizzare alcune librerie: sicuramente quelle di Hibernate (scaricabili da qui), ma non basta.
Per un semplice progetto, magari creato con un ambiente di sviluppo come NetBeans o Eclipse, servono anche le seguenti librerie:

  • i driver jdbc per il database che vogliamo utilizzare;
  • alcune librerie di Apache (in particolare le commons-logging e le commons-collections);
  • dom4j;
  • cglib;
  • asm;
  • jta.

I jar di queste librerie si trovano con una semplice ricerca su un qualsiasi motore oppure utilizzando Maven.
Una volta creato il nostro progetto sull'ambiente di sviluppo e aggiunte le librerie possiamo passare a scrivere il codice e fare il nostro primo programma con Hibernate.

Esempio

Come esempio usiamo ancora l'analogia dei libri e delle biblioteche. Utilizzeremo il mapping con il file xml.
Come prima cosa scriviamo le due classi java per l'entità Book e Library. La classe Book sarà del tutto simile a quella utilizzata nell'esempio della mappatura, senza le annotations.

package com.ventus85.test.hibernate;

public class Book{

    private int id;
    private String title;
    private String author;
    private String editor;

    public Book() {
    }

    public Book(String title, String author, String editor) {
        this.title = title;
        this.author = author;
        this.editor = editor;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getEditor() {
        return editor;
    }

    public void setEditor(String editor) {
        this.editor = editor;
    }
}

La classe Library sarà scritta allo stesso modo, con i suoi attributi, i metodi get e set, il costruttore vuoto (che, come detto, dovrà essere sempre presente), eventuali altri costruttori e metodi.

Il file datamodel.hbm.xml invece sarà come quello indicato in precedenza nella sezione della mappatura.
Il file hibernate.cfg.xml conterrà i riferimenti al database utilizzato (supponiamo di utilizzare un database postgres con username "test" e password "test") e il link al datamodel.hbm.xml.

<?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>
    <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.connection.url">jdbc:postgresql://localhost/</property>
    <property name="hibernate.connection.username">test</property>
    <property name="hibernate.connection.password">test<property>
    <property name="hibernate.current_session_context_class">thread</property>
    <mapping resource="com/ventus85/test/hibernate/datamodel.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

Infine dobbiamo scrivere il codice che andrà a scrivere e a leggere dal nostro database.
Nel nostro esempio useremo un semplice main:

package com.ventus85.test.hibernate;

import java.io.File;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

public class MainTest {
    public static void main(String[] args) {
        try {
            System.out.println("Start...");
            Book book = new Book("La divina commedia", "Dante Alighieri", "Mondadori srl");
            Library library = new Library("Biblioteca Le Oblate", "FI0104", "Via dell'Oriuolo 24", "50122", "Firenze");
            library.setPublicLibrary(true);
            String hibernatePropsFilePath = "/home/ventus85/Projects/Java/HibernateTest/src/hibernate.cfg.xml";
            File hibernatePropsFile = new File(hibernatePropsFilePath);
            Session session = new Configuration().configure(hibernatePropsFile).buildSessionFactory().getCurrentSession();
            session.beginTransaction();
            session.save(book);
            session.save(library);
            session.getTransaction().commit();
            System.out.println("Done...");
        } catch (Exception ex) {
            System.out.println("Error..." + ex);
        }
    }
}

In questo caso abbiamo passato, alla configurazione per Hibernate, direttamente il file hibernate.cfg.xml, altrimenti al metodo configure non passeremo nulla e il file dovrà essere obbligatoriamente salvato dentro la directory "src".
A questo punto non ci resta che creare il database (per esempio utilizzando pgAdmin III), le relative tabelle (Book e Library) e sequence (book_gen e library_gen) e lanciare il nostro main.
Dopo aver fatto eseguire il codice possiamo verificare che i due record sono stati salvati nelle relative tabelle e potremo usare una qualsiasi operazione CRUD per gestire il nostro progetto. E una volta fatto girare il nostro codice possiamo continuare a sviluppare scrivendo codice senza preoccuparci di gestire la persistenza dei nostri dati sui database, tanto ci pensa Hibernate!

Riferimenti

ventus85

Ingegnere informatico (del genere femminile) conosciuta nel web con il nickname “ventus85”. Sempre pronta a scroprire le nuove tecnologie e a studiare l’evoluzione informatica.

Hibernate - Introduzione ultima modifica: 2016-06-14T11:34:28+00:00 da ventus85


Advertisment ad adsense adlogger