
Cos’è Hibernate?
Hibernate è uno strumento open source di object-relational-mapping creato per Java: in parole povere, grazie ad esso (e in generale all’ORM) è possibile “mappare” un oggetto ad una determinata tabella di un database.
In particolare, il framework Hibernate mappa le classi Java in relazione alle tabelle di un database utilizzando due metodi: i file di configurazione XML (pratica ormai sempre più legata al passato) e le annotazioni Java.
Hibernate fornisce uno strato di astrazione con il quale è possibile interfacciarsi, mentre al suo interno svolge varie mansioni più complesse che altrimenti sarebbero totalmente a carico del programmatore.
Questi compiti interni e nascosti sono rappresentati ad esempio dall’esecuzione di query rivolte alle operazioni CRUD o all’inizializzazione delle connessioni ai database.
Una delle funzioni principali di Hibernate è quella di utilizzare una logica di persistenza, che permette ai dati di rimanere memorizzati a lungo termine; con logica di persistenza, quando si parla di Hibernate e Java, si intende l’immagazzinamento dei dati all’interno di un database relazionale (come SQL).
Hibernate è inoltre un’implementazione di JPA (Java Persistence API), una serie di specifiche relative all’ORM presenti su Java EE: Hibernate è uno degli strumenti per applicare queste specifiche per la comunicazione tra database e app.
Hibernate e JDBC
JDBC (Java Database Connectivity) è un API Java che si occupa di gestire le connessioni ai database, le query e i comandi, come anche i risultati ottenuti come risposta dal database.
Hibernate si pone “sopra” lo JDBC, rappresentando uno strato di persistenza indipendente dal tipo di database utilizzato: questo grazie alla facilità con cui è possibile cambiare “dialect“, ovvero la proprietà che specifica il tipo di database, direttamente all’interno del file di configurazione xml di Hibernate.
Con JDBC invece, in caso di cambio di database, il programmatore deve modificare manualmente varie parti del codice, con dispendio di tempo ed energia.
Altra caratteristica importante, per quanto riguarda la sua semplicità di utilizzo rispetto a JDBC, è il fatto di implementare i concetti della programmazione orientata agli oggetti per collegare un oggetto ad un database relazionale.
Tramite questo metodo, come dicevamo sopra, vengono mappate le classi alle tavole del database e al contempo, in modo automatico, Hibernate genera tutti i comandi SQL necessari per gestire le operazioni all’interno del database.
Questi comandi vengono impartiti utilizzando l’HQL (Hibernate Query Language) un linguaggio speciale (simile a SQL) proprio di Hibernate che permette di utilizzare i concetti fondamentali dell’ereditarietà, del polimorfismo e dell’associazione anche nella gestione dei database.
Con JDBC invece, tutti i compiti vengono impartiti utilizzando i comandi tradizionali SQL senza possibilità, naturalmente, di sfruttare i potenti concetti OOP.
Esempio di workflow con Hibernate
Di seguito un elenco delle operazioni che normalmente vengono svolte dal framework:
- Hibernate si collega al database e utilizzando l’HQL esegue le query, ottenendo i risultati dal database e mappandoli successivamente verso gli oggetti Java.
- I risultati vengono mappati sugli oggetti in base alle proprietà specificate all’interno del file XML, o nelle annotazioni all’interno del codice.
- Usando una sessione, viene creata la connessione tra app e database, sessione che serve anche per salvare e riaccedere in un secondo momento all’oggetto persistente; le istanze delle sessioni vengono “costruite” tramite un’interfaccia apposita chiamata
SessionFactory.
Vantaggi di Hibernate su JDBC
Impedance mismatch
Il compito principale a cui deve assolvere il framework è senza dubbio quello di risolvere la problematica dell’impedance mismatch.
Con questo termine complicato vogliamo descrivere l’incompatibilità che esiste tra un oggetto creato basandosi sulle regole dell’OOP (una classe Java, ad esempio) e un database relazionale.
Hibernate giunge in nostro aiuto permettendo una facile comunicazione tra queste due entità così differenti senza dover ricorrere a complicate operazioni di conversione.
Mappatura dell’oggetto
Con JDBC, l’onere di scrivere tutto il codice per mappare l’oggetto su un modello relazionale di un database spetta al programmatore. Con Hibernate, invece, basta configurare correttamente un file xml o le annotazioni e a tutto il resto ci penserà in automatico lui stesso; già solo questo punto ci fa comprendere l’indubbia utilità del framework, utilità che spazia comunque anche su altri fronti.
Ecco un esempio di codice che evidenzia il differente approccio alla mappatura degli oggetti tra JDBC e Hibernate:
//jdbc
list<user> users=new arraylist<user>();
while(rs.next()) { //"rs" è un'istanza dell'interfaccia "ResultSet", assegnata all'esecuzione di uno statement su una query.
user user = new user();
user.setuserid(rs.getstring("userid"));
user.setname(rs.getstring("firstname"));
user.setemail(rs.getstring(“email”));
users.add(user);
}
//hibernate
@Entity
@Table(name = "user")
public class usermodel {
@Id
@GeneratedValue(strategy = generationtype.identity)
private BigInteger id;
@NotEmpty
@Column(name = "email", unique = true)
private String email;
@NotEmpty
@Column(name = "name")
private String name;
public BigInteger getId() {
return this.id;
}
public void setId(biginteger id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(string email) {
this.email = email;
}
public String getName() {
return this.name;
}
public void setName(string name) {
this.name = name;
}
}
Come si può notare, con JDBC bisogna scrivere ogni volta le singole proprietà per mappare il database, mentre con Hibernate possiamo sfruttare l’OOP utilizzando una classe dotata di annotazioni che sarà il modello con il quale ogni volta il framework assocerà quel tipo di oggetto alle tavole del database.
Nota: ovviamente sarebbe possibile utilizzare un file xml invece delle annotazioni per raggiungere lo stesso scopo.
Per concludere
Esistono molti altri vantaggi nell’utilizzo di Hibernate rispetto a JDBC, come ad esempio la presenza di un sistema di caching, la riduzione della quantità di codice, la possibilità di eseguire facilmente le associazioni (come “one-to-one”, “one-to-many”, etc.) ed altro.
Dobbiamo ricordarci che Hibernate non è altro che un framework che si “appoggia” sopra a JDBC, facilitando di gran lunga tutte le operazioni che possiamo fare per gestire i rapporti tra database e applicazione.
Possiamo concludere affermando che, a parte forse per piccoli progetti, ad oggi risulta quasi sempre consigliabile utilizzare Hibernate rispetto a JDBC.