Pubblicato il 02/12/2023 da alnao nella categoria Java & Spring Boot

La libreria Hibernate è usata per creare una mappa tra le classi java e il modello di una base dati e si integra perfettamente con il concetto di persistenza dei dati verso il database visto che implementa le specifiche JPA (Java Persistence API) per la persistenza dei dati. In tutto il mondo è la libreria più usata anche da framework più evoluti come Spring e Spring Boot e. Come indicato nel sito ufficiale oltre alla libreria base per il collegamento con la base dati contiene anche altre sotto-librerie come la Hibernate Search (ricerca full-text), Hibernate Validator (gestione dei vincoli), Hibernate OGM (supporto Java Persistence per database NoSQL), Hibernate Tools (raccoglie strumenti a riga di comando e plug-in per lavorare con Hibernate).

Per importare la libreria in un progetto (dal semplice maven-archetype-quickstart al più complesso) basta importare nel pom.xml le librerie:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>4.3.5.Final</version>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.17</version>
</dependency>

come è possibile notare anche in questo caso è necessaria una libreria di connessione di tipo JDBC alla base dati, infatti la libreria necessita di un file di configurazione, che di solito si chiama hibernate.cfg.xml che i parametri di configurazione della base dati come la stringa di connessione, le credenziali e i parametri base, inoltre nel file di configurazione è necessario censire la lista delle classi

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://X.Y.Z.U:3306/uat</property>
    <property name="hibernate.connection.username">admin</property>
    <property name="hibernate.connection.password">xxxxxxx</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.show_sql">true</property>
    <property name="show_sql">true</property>
    <mapping class="it.alnao.hibernate.Model"/>
    <!-- <mapping resource="Models.xml"></mapping>-->
  </session-factory>
</hibernate-configuration>

Queste classi mapping definiscono la struttura dell’oggetto con le proprietà, con in aggiunta le informazioni della base dati con delle annotation, come il nome della tabella nella annotation table, il nome delle colonne e le proprietà nelle varie annotation previste dalla libreria

@Entity
@Table(name= "test_alberto", 
uniqueConstraints={@UniqueConstraint(columnNames={"id"} ) } ) 
public class Model{
  private long id;
  private String nome;
  private String cognome;
  
  @Id
  @Column(name = "id", unique = true, nullable = false)
  public long getId() {
    return id;
  }
  public void setId(long id) {
    this.id = id;
  }
 
  @Column(name = "nome")
  public String getNome() {
    return nome;
  }
  ....
}

Per funzionare la libreria deve essere caricata in esecuzione, prima delle operazioni dei database quindi viene spesso definita una classe di utilità per il recupero della libreria e del file di configurazione:

public class HibernateUtil {
 private static final SessionFactory sessionFactory = buildSessionFactory();
 private static SessionFactory buildSessionFactory() {
  SessionFactory sessionFactory = null;
  try {
    Configuration configuration = new Configuration();
    configuration.configure("hibernate.cfg.xml");
    System.out.println("Hibernate Configuration loaded");
    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
      .applySettings(configuration.getProperties()).build();
    System.out.println("Hibernate serviceRegistry created");
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    return sessionFactory;
  }catch (Exception e) {
    e.printStackTrace();
  }
  return sessionFactory;
 }
 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }
}

Per richiamare la libreria ed eseguire operazioni sul database è necessario richiamare prima la classe di utilità e poi si possono eseguire le operazioni sulla base dati:

public static void main( String[] args ) {
  Model m=new Model();
  m.setId(1);
  m.setNome("Alberto");
  m.setCognome("Nao");
  Session session = HibernateUtil.getSessionFactory().openSession();
  try{
    session.save(m); 
    session.flush();
    System.out.println("Saved Successfully.");
    Query q = session.createQuery("from Model");
    List<Model> resultList = q.list();
    System.out.println("num:" + resultList.size());
    for (Model next : resultList) {
      System.out.println("- " + next);
    }
    session.delete(resultList.get(0));
  }catch (Exception e) {
    e.printStackTrace(); 
  }finally {
    session.close(); 
  } 
}

Come notato in questo semplice esempio viene inserito un elemento, viene eseguita una query di selezione e successivamente viene cancellato. La query viene eseguita con il linguaggio HQL (Hibernate Query Language) che è molto simile al SQL con la differenza che si usano i nomi java e non i nomi della base dati. Si rimanda alla documentazione ufficiale per maggior informazioni riguardo a questa tecnica.

La libreria permette di censire i modelli come file xml al posto delle classi java: nel file di configurazione si deve aggiungere il riferimento ad un file xml esterno (come possibile vedere nell’esempio sopra nella riga commentata) e in questo file si devono censire la lista delle tabelle e la classe corrispondente e la lista di tutti i campi della base dati con i nomi delle proprietà java corrispondenti. Per esempio:

<hibernate-mapping package="it.alnao.hibernate">
  <class name="Model" table="test_alberto" >
    <id name="id" type="long" column = "id">
      <generator class="native"/>
    </id>
    <property name="nome" type="string" column="name" />
    <property name="cognome" type="string" column="cognome" />
  </class>
</hibernate-mapping>

Questa tecnica eviterebbe l’uso delle tante annotation nelle classi java, tuttavia nel tempo non è stata molto usata e ha sempre più preso piede l’uso delle classi con le annotation senza il mapping separato, tecnica che sarà spesso usata nei prossimi esempi visto che per Spring Boot è lo standard.

Questa libreria con queste tecnica permette di costruire applicazioni perfettamente in linea con la filosofia del MVC, dove Hibernate e il suo file di configurazione si prende il compido del Model, delegando ad altre librerie (come Struts o Spring) il compito di gestire le View e il controller.

MENU