49

ORM Java - Hibernate

Embed Size (px)

Citation preview

Scrivere applicazioni Java con Hibernate Di Massimiliano Brolli

Premessa ................................................................................................... 3

Prerequisiti ................................................................................................ 4

Il motore di Hibernate ................................................................................. 5

L’ambiente per Hibernate ............................................................................. 6

Installazione dei Plug-In per Eclipse .............................................................. 7

Sviluppiamo il nostro progetto ...................................................................... 8

Importiamo le librerie necessarie ............................................................... 8

Uno sguardo allo schema delle tabelle che andremo ad utilizzare ................... 9

Creiamo i Package necessari ..................................................................... 9

Configurazione di Hibernate .................................................................... 10

Creiamo il file hibernate.cfg.xml ............................................................ 10

Creazione delle classi di Mapping tramite Plug-In ....................................... 12

Creiamo la Console Configuration con Hibernate Tools ............................. 12

Creiamo Il reverse Engigneering con Hibernate Tools ............................... 15

Creiamo le classi di Mapping ................................................................. 17

La Session Factory ................................................................................. 19

Diamo uno sguardo alla prospettiva Hibernate ........................................... 21

Implementiamo la nostra Applet di test .................................................... 23

Operazioni CRUD sulla tabella Users ......................................................... 27

Create ............................................................................................... 27

Read ................................................................................................. 27

Update ............................................................................................... 28

Delete ............................................................................................... 29

Operazioni di associazione tra Users e Groups ........................................... 29

Associazione di una Users ad un Gruppo ................................................ 31

Visualizzazione delle associazioni .......................................................... 31

Le Annotations ...................................................................................... 33

La sintassi HQL (Hibernate Query Language) ............................................. 37

Esempio di select in HQL ...................................................................... 38

Esempio di Join in HQL......................................................................... 39

Left e Right in SQL .............................................................................. 40

Left e Right in HQL .............................................................................. 43

Utilizzo di SQL Nativo in Hibernate ........................................................... 45

Il codice completo dell’Applet Swing ......................................................... 45

Bibliografia ............................................................................................ 49

Premessa Lavorare con un software object-oriented e un database relazionale può essere impegnativo e consumare tempo nelle realtà aziendali di oggi. Hibernate è uno strumento di Object Relational Mapping (ORM) per gli ambienti Java. Il termine ORM si riferisce ad una logica di mappatura di una rappresentazione di dati da un modello relazionale ad un modello ad oggetti seguendo uno schema SQL-based.

Hibernate non si prende in carico solo il mapping di classi java verso tabelle di database (e da tipi di dati java verso tipi di dati SQL), ma fornisce la possibilità di eseguire query sui dati presenti nel DB e di gestirne i risultati in maniera molto semplificata. L’obiettivo di Hibernate è quello di liberare il programmatore dalla scrittura di stringhe SQL e lo fa per il 95% della comune fase di programmazione relativa alla persistenza dei dati, il tutto riducendo in maniera significativa i tempi di sviluppo e di debug. In sintesi Hibenate si pone tra il modello ad oggetti che si ricava dalla logica della nostra applicazione e l’insieme delle tabelle, chiavi primarie e vincoli relazionali presente su di una base dati. E’ importante sottolineare che Hibernate è disponibile anche nel mondo Microsoft .NET sotto il nome di NHibernate e che esistono differenti tecnologie ORM come in ambiente Microsoft ADO.NET Entity Framework.

Prerequisiti Per procedere alla lettura di questo documento occorre aver letto le seguenti dispense :

• Introduzione agli algoritmi. • La scelta tra Microsoft.NET & Java • Predisposizione Virtual Machine di base • Predisposizione Virtual Machine per l'ambiente di sviluppo Java • Introduzione alla scrittura del codice JAVA • Scrivere applicazioni JAVA con Eclipse • Panoramica sulla programmazione ad oggetti • La Storia • Predisposizione ambiente MySQL • Scrivere Java Application • Scrivere Java Web Application, Premessa e predisposizione • Scrivere Java Web Application con Servlet e JSP • Scrivere Java Web Services con AXIS2

Il motore di Hibernate Il motore persistente di Hibernate può occuparsi di tutto il lavoro necessario per estrarre, inserire e modificare i dati (operazioni CRUD, acronimo di Create Read

Update and Delete) che costituiscono lo stato degli oggetti del nostro dominio applicativo generando autonomamente e in tutta trasparenza i comandi e le interrogazioni SQL necessari. Il tutto è basato su di un approccio di tipo dichiarativo tramite l’utilizzo di uno o più file hbm.xml di configurazione che stabiliscono la corrispondenza tra gli oggetti della nostra applicazione e le tabelle del database. Una volta definite queste associazioni, l'infrastruttura che utilizzeremo si occuperà di recuperare dinamicamente le informazioni associate (leggendo i descrittori) e creare automaticamente le query necessarie (in base all'operazione che utilizzeremo).

L’ambiente per Hibernate Più che installazione, bisogna parlare di importazione di librerie (jar) che contengono la logica del middleware di Hibernate. Dal sito ufficiale potete raggiungere la pagina di download e scaricare il materiale necessario ad iniziare. La tecnologia è particolarmente complessa nelle sue funzionalità avanzate e nel sito troverete tutto il materiale di cui avrete bisogno per approfondimenti. Per iniziare è sufficiente scaricare la tecnologia core, arrivata, al momento in cui scrivo, alla versione 3.6.5. E’ importante inoltre scaricare i Plug-In messi a disposizione dal RAD JBOSS-

IDE compatibili con Eclipse di modo da poter sviluppare comodamente le classi model evitando la scrittura manuale dei file di configurazione e classi di mapping in Java.

Installazione dei Plug-In per Eclipse Eseguiamo la procedura di installazione dei Plug-In per Hibernate Tools disponibili sul sito JBOSS. Utilizzate la Url http://download.jboss.org/jbosstools/updates/stable. La procedura di installazione è presente all’interno del documento 4 - Scrivere

applicazioni JAVA con Eclipse capitolo Installazione dei Plug-In per Eclipse Una volta installati dal Menu Window e poi Open Perspective sarà possibile visualizzare la prospettiva Hibernate.

Sviluppiamo il nostro progetto Apriamo Eclipse e creiamo un nuovo progetto di tipo Java Project che andremo a chiamare HibernateExampleProject e clicchiamo su Finish.

Importiamo le librerie necessarie

Ora andiamo a creare una User Library (facendo riferimento al capitolo Creazione di User Library di Eclipse del documento 4 - Scrivere applicazioni

JAVA con Eclipse) che andremo a chiamare Hibernate. Al suo interno importiamo tutti i JAR scaricati dal sito di Hibernate, comunque quelli necessari per far funzionare questo tutorial sono quelli riportati nella print screen successiva.

Inoltre importiamo all’interno del progetto anche la User Library creata in precedenza MySQL Driver nella quale sarà presente il Driver JDBC utilizzato per l’accesso su MySQL Utilizzando le User Library nel mio caso avrò importate le seguenti librerie e il progetto completo risulterà come il seguente.

Uno sguardo allo schema delle tabelle che andremo ad utilizzare Come oramai immaginate, andremo ad utilizzare le tabelle create in precedenza quando abbiamo effettuato la predisposizione dell’ambiente MySQL e le tabelle che andremo ad utilizzare sono la tabella Users, la tabella Groups e l’associativa UsersGroups. Riporto lo schema di seguito di modo da facilitare la comprensione delle relazioni e il successivo mapping che verrà effettuato da Hibernate.

Creiamo i Package necessari

E’ importante quando abbiamo a che fare con progetti di grandi dimensioni strutturare l’ambiente di programmazione in maniera ottimale pertanto andremo a creare una serie di Package per strutturare meglio il lavoro e rendere il progetto facilmente manutenibile.

Procediamo quindi nella creazione dei seguenti Package :

• configuration

• hibernate.model • sessionFactory

• userInterface Il contenuto di tali Package verrà dettagliato nei paragrafi di seguito.

Configurazione di Hibernate

Andiamo ora ad effettuare una serie di operazioni (creazioni files e Wizard tramite Hibernate Tools) per configurare l’ambiente e in primis andiamo a creare il file principale della nostra configurazione Hibernate, il file hibernate.cfg.xml.

Creiamo il file hibernate.cfg.xml

Il file contiene le informazioni di configurazione di Hibernate nonché i puntamenti al mapping delle tabelle. Andiamo manualmente a creare tale file hibernate.cfg.xml all’interno della cartella src e andiamo quindi ad incollare il seguente codice. <?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="connection.url">jdbc:mysql://localhost/corsojava</property>

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="connection.username">root</property>

<property name="connection.password">Paperino2005</property>

<property name="hbm2ddl.auto">validate</property>

<property name="show_sql">true</property>

<property name="format_sql">true</property>

<property name="use_sql_comments">true</property>

</session-factory>

</hibernate-configuration>

Le principali proprietà presenti nel file sono :

• connection.driver_class : Contiene il driver Jdbc che verrà utilizzato per la connessione al database, nel nostro caso il connettore presente nel Jar importato in precedenza.

• connection.url : Il puntamento allo schema del database MySQL che nel nostro caso è lo schema corsojava creato in precedenza.

• connection.username : L’utenza di connessione al database/schema.

• connection.password : La password relativa all’utenza specificata precedentemente.

• dialect : dialetto SQL utilizzato e presente nel driver Jdbc di connessione alla base dati. I principali dialetti vengono sotto riportati :

o MySQL net.sf.hibernate.dialect.MySQLDialect

o DB2 net.sf.hibernate.dialect.DB2Dialect o SAP DB net.sf.hibernate.dialect.SAPDBDialect o Oracle (any version) net.sf.hibernate.dialect.OracleDialect o Oracle 9 net.sf.hibernate.dialect.Oracle9Dialect o Sybase net.sf.hibernate.dialect.SybaseDialect o Sybase net.sf.hibernate.dialect.SybaseAnywhereDialect o Progress net.sf.hibernate.dialect.ProgressDialect o Mckoi SQL net.sf.hibernate.dialect.MckoiDialect o Interbase net.sf.hibernate.dialect.InterbaseDialect o Pointbase net.sf.hibernate.dialect.PointbaseDialect o PostgreSQL net.sf.hibernate.dialect.PostgreSQLDialect o HypersonicSQL net.sf.hibernate.dialect.HSQLDialect o Microsoft SQL Server net.sf.hibernate.dialect.SQLServerDialect o Ingres net.sf.hibernate.dialect.IngresDialect o Informix net.sf.hibernate.dialect.InformixDialect o FrontBase net.sf.hibernate.dialect.FrontbaseDialect

• hbm2ddl : Permette di specificare particolari azioni da effettuare in fase di creazione della sessione Hibernate (SessionFactory) I valori possono essere :

o Auto : Esporta automaticamente lo schema DDL sul database quando viene creata la sessione, lo schema di database verrà eliminato subito dopo che la sessione verrà eliminata.

o validate : valida lo schema in relazione agli oggetti di persistenza e non procede ad alcun aggiornamento.

o update : Aggiorna lo schema se questo non è congruente con le classi di mapping. create : Crea lo schema.

o Create-drop : elimina lo schema di database subito dopo che la sessione verrà chiusa esplicitamente.

• mapping : Ancora non presenti nel nostro esempio XML, riporteranno i file di risorsa che fanno riferimento agli oggetti che mapperanno le tabelle Hibernete quali la classe users e la classe usersgroups come vedremo più avanti.

• Show_sql : Permette di visualizzare sulla console le query sql generate ed eseguite.

• Format_sql :Permette di formattare le query sql in modo leggibile e non su un’unica linea dando modo ad una verifica più immediata.

• use_sql_comments : Permette di visualizzare i commenti auto generati da hibernate in fase di lancio delle query.

Tutte queste proprietà definiscono la configurazione della connessione JDBC oltre che a particolari azioni da effettuare da parte di Hibernate sullo schema dati.

Ovviamente in una applicazione di esercizio il valore non potrà essere altro che validate, mentre in sviluppo potrebbe essere valutato tra le varie opzioni disponibili. E’ inoltre importante dire che tale file è possibile crearlo e modificarlo tramite i Plug-in di eclipse, infatti come mostra la maschera successiva è possibile scegliere tale creazione guidata specificando nel menu File->New->Other Hibernate.

Creazione delle classi di Mapping tramite Plug-In

Predisposta la configurazione dell’ambiente Hibernate, procediamo alla creazione delle classi di Mapping utilizzando le funzionalità offerte dai Plug-In di Eclipse. Per poter utilizzare tali funzionalità è necessario disporre di una Console Application per permettere l’accesso alla base dati e di un reverse

Engigneering che permetterà la trasformazione in classi delle tabelle del database.

Creiamo la Console Configuration con Hibernate Tools

Ora andiamo a creare la Console Configuration per permettere l’accesso al database ai plug-in di Hibernate Tools di Eclipse.

Per far questo clicchiamo con il tasto destro sul nome del progetto e selezioniamo New e poi Other. Nella maschera andiamo a cliccare su Hibernate Console Configuration. Clicchiamo su Next.

Nella maschera visualizzata andiamo a riportare le informazioni necessarie alla sua configurazione specificando in Database Connection [Hibernate configured connection], valore di default e clicchiamo su Finish

Cliccando su Finish Eclipse non fornirà alcuna notifica di creazione della Console

Configuration, queste saranno manutenibili cliccando con il tasto destro sul progetto e poi Run As e cliccando su Run Configuration.

In questo modo sarà possibile modificarle e gestirle.

Creiamo Il reverse Engigneering con Hibernate Tools

Ora dobbiamo andare a creare il Reverse Engineering che ci permetterà di creare le classi di mapping in maniera automatica evitandoci di scriverle manualmente ogni volta connettendosi al database tramite la Console

Configuration creata al paragrafo precedente. Clicchiamo su new e poi Other, selezioniamo Hibernate Reverse Engineering e clicchiamo su Next.

Nella maschera successiva andiamo a selezionare la cartella configuration creata in precedenza nella quale verrà memorizzato il file di configurazione del Reverse Engineering e quindi clicchiamo su Next.

Ora andiamo a selezionare Table Filters nel file XML del Reverse Engineering e clicchiamo su Refresh. A questo punto il Wizard si connette alla base dati utilizzando la Console

Configuration la quale utilizza il file hibernate.cfg.xml nella quale sono memorizzati i puntamenti e utenze/password del database ci rende disponibile lo schema del nostro database nel box a sinistra della maschera. Espandiamo lo schema ed evidenziamo la tabella groups e clicchiamo su Include. Facciamo questo per tutte le tabelle dello schema. Ora clicchiamo su Finish.

Il Wizard quindi creerà il file hibernate.reveng.xml all’interno della cartella Configuration nel quale saranno memorizzate le seguenti informazioni in formato XML. <?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

<hibernate-reverse-engineering>

<table-filter match-catalog="corsojava" match-name="groups"/>

<table-filter match-catalog="corsojava" match-name="users"/>

<table-filter match-catalog="corsojava" match-name="usersgroups"/>

</hibernate-reverse-engineering>

Di fatto non farà altro che includere al suo interno le tabelle precedentemente incluse tramite il Wizard.

Creiamo le classi di Mapping

Ora dobbiamo creare in modo automatico, tramite i Plug-In di Eclipse le classi di Mapping e i file di configurazione di Hibernate che permetteranno al framework di lavorare con il database. Per far questo clicchiamo cul triangolino mostrato nella figura precedente presente nella Tollbar e poi selezioniamo dalla tendina Hibernate Code

Generation Configurations.

Verrà mostrata la maschera seguente dove cliccheremo sulla icona ina alto a sinistra raffigurante il simbolo più Più per creare una nuova configurazione.

1. Inseriamo nel box Name il valore Export. 2. Inseriamo nel box Output directory la directory src del nostro progetto. 3. Clicchiamo se non già fleggato la voce Reverse engineer from JDBC

Connection, tale azione renderà editabili i valori sotto riportati. 4. Inseriamo nel box Package il valore hibernate.model.

5. Clicchiamo sul tab Exporters.

Flegghiamo la voce Use Java 5 syntax. 6. Flegghiamo Domain code (.java)

7. Flegghiamo Hibernate XML Mapping (.hbm) 8. Come riporta la figura successiva.

A questo punto clicchiamo sun Run, verrà avviata la fase di creazione.

Verranno quindi creati tutti gli oggetti nel package hibernate.model, a questo punto però occorrerà fare un po’ di ordine. Andiamo ad organizzare i files fino ad ora creati come viene mostrato nella figura successiva raffigurante il progetto della nostra soluzione. Di fatto tutti i file contenenti configurazioni XML Hibernate li andremo ad inserire all’interno del package Configuration tranne hibernate.cfg.xml che dovrà essere disponibile all’interno della cartella src.

E andiamo ad editare il file hibernate.cfg.xml in quanto dovremo inserire i tag mapping riferiti ai file xml generati in precedenza i quali non verranno generati in maniera automatica dal Wizard. Il nostro file di configurazione avrà il seguente codice. <?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="connection.url">jdbc:mysql://localhost/corsojava</property>

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="connection.username">root</property>

<property name="connection.password">Paperino2005</property>

<property name="hbm2ddl.auto">validate</property>

<property name="show_sql">true</property>

<property name="format_sql">true</property>

<property name="use_sql_comments">true</property>

<mapping resource="configuration/Users.hbm.xml"/>

<mapping resource="configuration/Groups.hbm.xml"/>

</session-factory>

</hibernate-configuration>

La Session Factory

Bene, arrivati a questo punto abbiamo a disposizione tutto il necessario per poter lavorare i nostri dati tramite Hibernate e per poterlo fare dobbiamo andare a creare è una classe che ci permetta di instaurare una sessione Hibernate di comunicazione che si chiama SessionFactory. Creiamo quindi la classe CustomSessionFactory all’interno del package hibernate.sessionFactory creato in precedenza. Incolliamo al suo interno il codice presente di seguito. package sessionFactory;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class CustomSessionFactory {

private static final SessionFactory sessionFactory;

static {

try {

sessionFactory = new Configuration().configure().buildSessionFactory();

} catch (Throwable ex) {

System.err.println("Initial SessionFactory creation failed." + ex);

throw new ExceptionInInitializerError(ex);

}

}

public static SessionFactory getSessionFactory() {

return sessionFactory;

}

}

Fondamentalmente la SessionFactory permette la creazione delle Sessione Hibernate quindi la creazione dell’istanza dell’oggetto configuration il quale permetterà di accedere alla base dati prendendo in input le informazioni di configurazione fatte in precedenza all’interno del file hibernate.cfg.xml

La Factory una volta creata legge dai tag mapping sempre presenti in hibernate.cfg.xml i puntamenti ai file di configurazione di mapping della tabelle i quali a sua volta forniranno indicazioni sul package e il nome delle classi Java (nel nostro caso presenti in hibernate.model) che incapsuleranno le operazioni CRUD per le specifiche tabelle. La classe SessionFactory di fatto è la classe che crea il contesto/sessione Hibernate, senza di essa non sono possibili attività sul database.

Diamo uno sguardo alla prospettiva Hibernate

Ora se accediamo alla prospettiva Hibernate (viene descritto come attivarla nella dispenza Scrivere applicazioni JAVA con Eclipse) possiamo accedere ad una serie di viste sul contesto Hibernate appena Generato.

Noteremo che sarà presente il nome del Progetto presente a sua volta nella prospettiva Java e sotto di esso una serie di viste che possono essere riassunte in :

• Configuration : Contiene informazioni sulla configurazione del mapping, è possibile infatti accedere con il tasto destro sull’oggetto sia alla classe che al file di configurazione.

• SessionFactory : Contiene il contesto/sessione Hibernate presente ovviamente solo se esiste una classe SessionFactory. Tramite questa vista è possibile visualizzare i metodi messi a disposizione dalle classi di Mapping

• Database : Il link alla base dati messo a disposizione dalla Console

Configuration e dal Reverse Engigneering precedentemente creati. Se clicchiamo su un oggetto presente nella vista Configuration con il tasto destro e selezioniamo Open Mapping Diagram verrà visualizzato graficamente dai Plug-In il mapping effettuato tra la tabella del database e l’oggetto selezionato oltre alla visualizzazione della referenza tra la tabella Users e la tabella Groups gestita da Hibernate.

Implementiamo la nostra Applet di test

Ora andiamo ad implementare la nostra applicazione di test la quale sarà una Java Application che utilizzerà come componenti le Swing di Java. Andiamo quindi a creare la nostra classe che chiameremo TestHibernate la quale avrà il seguente aspetto.

Di seguito l’associazione tra i nomi degli oggetti e le descrizioni presenti all’interno delle label.

• Il jTextBox di User id si chiamerà jTextUserid • Il jTextBox di Password si chiamerà jTextPassword • Il jTextBox di Nome si chiamerà jTextName • Il jTextBox di Cognome si chiamerà jTextSurname

• la jComboBox di Gruppo si chiamerà jComboBoxGroups

• Il jBotton di Associa si chiamera JButtonAssociate • Il jBotton di Visualizza si chiamera jButtonViewGroups

• Il jBotton di Inserisci si chiamera jButtonInsert • Il jBotton di Modifica si chiamera jButtonChange • Il jBotton di Cancella si chiamera jButtonDelete • Il jBotton di Ricerca si chiamera jButtonSearch

Creiamo gli eventi mouseClicked() per ogniuno dei jButton presenti. Per far questo fate riferimento al documento Scrivere Java Application precedentemente letto. Al termine della creazione della nostra Java Application, il risultato del codice generato tramite Visual Editor sarà il presente :

package userInterface;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.Transaction;

import org.hibernate.Query.*;

import hibernate.model.*;

import javax.swing.*;

import sessionFactory.CustomSessionFactory;

import java.awt.Dimension;

import java.awt.Rectangle;

import java.util.Iterator;

import java.util.List;

import java.util.Set;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JComboBox;

public class TestHibernate extends JFrame {

private static final long serialVersionUID = 1L;

private JPanel jContentPane = null;

private JLabel jLabel = null;

private JLabel jLabel1 = null;

private JTextArea jTextArea = null;

private JTextField jTextSurname = null;

private JLabel jLabel2 = null;

private JLabel jLabel3 = null;

private JTextField jTextUserid = null;

private JTextField jTextPassword = null;

private JTextField jTextName = null;

private JScrollPane jScrollPane = null;

private JButton jButtonSearch = null;

private JButton jButtonChange = null;

private JButton jButtonDelete = null;

private JLabel jLabel4 = null;

private JComboBox jComboBoxGroups = null;

private JButton jButtonInsert = null;

private JButton jButtonAssociate = null;

private JButton jButtonViewGroups = null;

private JTextArea getJTextArea() {

if (jTextArea == null) {

jTextArea = new JTextArea();

}

return jTextArea;

}

private JTextField getJTextSurname() {

if (jTextSurname == null) {

jTextSurname = new JTextField();

jTextSurname.setBounds(new Rectangle(106, 58, 360, 16));

}

return jTextSurname;

}

private JTextField getJTextUserid() {

if (jTextUserid == null) {

jTextUserid = new JTextField();

jTextUserid.setBounds(new Rectangle(106, 15, 106, 16));

}

return jTextUserid;

}

private JTextField getJTextPassword() {

if (jTextPassword == null) {

jTextPassword = new JTextField();

jTextPassword.setBounds(new Rectangle(314, 15, 151, 16));

}

return jTextPassword;

}

private JTextField getJTextName() {

if (jTextName == null) {

jTextName = new JTextField();

jTextName.setBounds(new Rectangle(106, 37, 360, 16));

}

return jTextName;

}

private JScrollPane getJScrollPane() {

if (jScrollPane == null) {

jScrollPane = new JScrollPane();

jScrollPane.setBounds(new Rectangle(15, 100, 455, 127));

jScrollPane.setViewportView(getJTextArea());

}

return jScrollPane;

}

public TestHibernate() {

super();

initialize();

}

private void initialize() {

this.setSize(490, 291);

this.setContentPane(getJContentPane());

this.setTitle("JFrame");

}

private void log(String value){

jTextArea.setText(jTextArea.getText() + "\n" + value);

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jLabel4 = new JLabel();

jLabel4.setBounds(new Rectangle(16, 78, 77, 16));

jLabel4.setText("Gruppo :");

jLabel3 = new JLabel();

jLabel3.setBounds(new Rectangle(16, 58, 79, 16));

jLabel3.setText("Cognome :");

jLabel2 = new JLabel();

jLabel2.setBounds(new Rectangle(16, 37, 76, 16));

jLabel2.setText("Nome :");

jLabel1 = new JLabel();

jLabel1.setBounds(new Rectangle(224, 15, 80, 16));

jLabel1.setText("Password : ");

jLabel = new JLabel();

jLabel.setBounds(new Rectangle(16, 15, 81, 16));

jLabel.setText("User id :");

jContentPane = new JPanel();

jContentPane.setLayout(null);

jContentPane.add(jLabel, null);

jContentPane.add(jLabel1, null);

jContentPane.add(getJTextSurname(), null);

jContentPane.add(jLabel2, null);

jContentPane.add(jLabel3, null);

jContentPane.add(getJTextUserid(), null);

jContentPane.add(getJTextPassword(), null);

jContentPane.add(getJTextName(), null);

jContentPane.add(getJScrollPane(), null);

jContentPane.add(getJButtonSearch(), null);

jContentPane.add(getJButtonChange(), null);

jContentPane.add(getJButtonDelete(), null);

jContentPane.add(jLabel4, null);

jContentPane.add(getJComboBoxGroups(), null);

jContentPane.add(getJButtonInsert(), null);

jContentPane.add(getJButtonAssociate(), null);

jContentPane.add(getJButtonViewGroups(), null);

}

return jContentPane;

}

private JButton getJButtonSearch() {

if (jButtonSearch == null) {

jButtonSearch = new JButton();

jButtonSearch.setBounds(new Rectangle(136, 231, 93, 26));

jButtonSearch.setText("Ricerca");

jButtonSearch.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

System.out.println("mouseClicked()"); // TODO Auto-generated Event

stub mouseClicked()

}

});

}

return jButtonSearch;

}

private JButton getJButtonChange() {

if (jButtonChange == null) {

jButtonChange = new JButton();

jButtonChange.setBounds(new Rectangle(251, 231, 97, 26));

jButtonChange.setText("Modifica");

jButtonChange.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

}

});

}

return jButtonChange;

}

private JButton getJButtonDelete() {

if (jButtonDelete == null) {

jButtonDelete = new JButton();

jButtonDelete.setBounds(new Rectangle(370, 231, 98, 26));

jButtonDelete.setText("Cancella");

jButtonDelete.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

}

});

}

return jButtonDelete;

}

private JComboBox getJComboBoxGroups() {

if (jComboBoxGroups == null) {

jComboBoxGroups = new JComboBox();

jComboBoxGroups.setBounds(new Rectangle(106, 78, 137, 16));

}

return jComboBoxGroups;

}

private JButton getJButtonInsert() {

if (jButtonInsert == null) {

jButtonInsert = new JButton();

jButtonInsert.setBounds(new Rectangle(16, 231, 98, 26));

jButtonInsert.setText("Inserisci");

jButtonInsert.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

}

});

}

return jButtonInsert;

}

private JButton getJButtonAssociate() {

if (jButtonAssociate == null) {

jButtonAssociate = new JButton();

jButtonAssociate.setBounds(new Rectangle(247, 78, 114, 17));

jButtonAssociate.setText("Associa");

jButtonAssociate.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

}

});

}

return jButtonAssociate;

}

/**

* This method initializes jButtonViewGroups

*

* @return javax.swing.JButton

*/

private JButton getJButtonViewGroups() {

if (jButtonViewGroups == null) {

jButtonViewGroups = new JButton();

jButtonViewGroups.setBounds(new Rectangle(362, 78, 105, 17));

jButtonViewGroups.setText("Visualizza");

jButtonViewGroups.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

}

});

}

return jButtonViewGroups;

}

} // @jve:decl-index=0:visual-constraint="10,10"

Operazioni CRUD sulla tabella Users

Ora andiamo a capire come richiamare Hibernate per poter effettuare operazioni CRUD sull’oggetto users appena creato tramite gli Hibernate Tools.

Create

Bene, ora andiamo a selezionare il tasto Inserisci, Visual Editor si posizionerà in automatico all’interno della routine dove andremo ad inserire il seguente codice. Verrà creato un oggetto di tipo Session tramite la chiamata alla classe CustomSessionFactory la quale ci fornirà il contesto Hibernate sul quale andremo a lavorare. Creeremo un oggetto transaction il quale ci permetterà di poter abolire le precedenti modifiche sul database in seguito ad un errore gestito dal codice try/Catch. Verrà quindi creato un oggetto Users al quale tramite i metodi set verranno impostati i valori prelevati dagli oggetti Swing JTextBox. Tramite la chiamata al metodo save() dell’istanza session andremo a salvare sulla base dati quanto abbiamo valorizzato all’interno dell’oggetto Users. Il metodo save() infatti prende in input l’istanza precedentemente creata e valorizzata di Users.

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Users u = new Users();

u.setIdUsers(jTextUserid.getText());

u.setIdPassword(jTextPassword.getText());

u.setName(jTextName.getText());

u.setSurname(jTextSurname.getText());

session.save(u);

transaction.commit();

log("Inserimento avvenuto!");

} catch (HibernateException ex) {

transaction.rollback();

log("Inserimento non avvenuto!");

log(ex.getMessage());

} finally {

session.close();

}

Read

Andiamo a selezionare il tasto Ricerca, Visual Editor si posizionerà in automatico all’interno della routine nella quale andremo ad incollare il seguente codice.

In questo caso verrà eseguito il metodo sessionQuery() sull’istanza session la quale genererà un oggetto List nel quale saranno presenti gli oggetti Users valorizzati con i dati presenti sul database. Per ricercare quindi un utente presente nel database valorizzare il box User id e cliccare su Ricerca. String textFind = jTextUserid.getText();

jTextArea.setText("");

jTextUserid.setText("");

jTextPassword.setText("");

jTextName.setText("");

jTextSurname.setText("");

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

List us = session.createQuery("from Users").list();

for (Iterator iterator = us.iterator(); iterator.hasNext();){

Users u = (Users) iterator.next();

if (textFind.equals(u.getIdUsers())){

jTextUserid.setText(u.getIdUsers());

jTextPassword.setText(u.getIdPassword());

jTextName.setText(u.getName());

jTextSurname.setText(u.getSurname());

}

log("idUser : " + u.getIdUsers());

log("idPassword : " + u.getIdPassword());

log("Name : " + u.getName());

log("Surname : " + u.getSurname());

}

transaction.commit();

} catch (HibernateException ex) {

transaction.rollback();

log("Inserimento non avvenuto!");

log(ex.getMessage());

} finally {

session.close();

}

Update

Andiamo a selezionare il tasto Modifica, Visual Editor si posizionerà in automatico all’interno della routine nella quale andremo ad incollare il seguente codice. Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Users u = (Users) session.get(Users.class, jTextUserid.getText());

u.setIdPassword(jTextPassword.getText());

u.setName(jTextName.getText());

u.setSurname(jTextSurname.getText());

transaction.commit();

log("Modifica avvenuta!");

} catch (HibernateException ex) {

transaction.rollback();

log("Modifica non avvenuta!");

log(ex.getMessage());

} finally {

session.close();

}

Delete

Andiamo a selezionare il tasto Cancella, Visual Editor si posizionerà in automatico all’interno della routine nella quale andremo ad incollare il seguente codice. Ovviamente per cancellare l’occorrenza occorrerà prima ricercarla e poi una volta presente si potrà cliccare sul tasto Cancella. Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Users u = (Users) session.get(Users.class, jTextUserid.getText());

session.delete(u);

transaction.commit();

log("Modifica avvenuta!");

} catch (HibernateException ex) {

transaction.rollback();

log("Modifica non avvenuta!");

log(ex.getMessage());

} finally {

session.close();

}

Operazioni di associazione tra Users e Groups

Ora andiamo ad inserire all’interno della tendina Gruppo i valori presenti nella tabella Groups mappatta dal nostro oggetto Groups creato in precedenza. Andiamo quindi ad inserire il codice presente di seguito all’interno del costruttore della nostra Applet subito dopo il metodo Inizialize().

Questo ci permetterà di andare a mostrare all’interno della tendina jComboBoxGroups le descrizioni dei gruppi presenti nella tabella Groups. Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

List gr = session.createQuery("from Groups").list();

for (Iterator iterator = gr.iterator(); iterator.hasNext();){

Groups g = (Groups) iterator.next();

jComboBoxGroups.addItem(g.getIdGroups());

}

transaction.commit();

} catch (HibernateException ex) {

transaction.rollback();

log("Inserimento non avvenuto!");

log(ex.getMessage());

} finally {

session.close();

}

Associazione di una Users ad un Gruppo

Al click sul tasto Associa andremo ad associare l’utenza precedentemente ricercata nel gruppo visualizzato all’interno della tendina Gruppo. Per far questo dovremo per prima cosa creare una istanza dell’oggetto Groups e dell’oggetto Users. Accederemo alla proprietà getGroupses della classe Users per prelevarne l’istanza groupses la quale conterrà un oggetto di tipo Java.Util.Set nel quale saranno presenti tutte gli oggetti Groups associati alla nostra utenza. Fatto questo andremo ad associare il nuovo gruppo (precedentemente generato) all’istanza groupses e successivamente la andremo a settare tramite la proprietà setGroupses. E’ importante sottolineare che se avessimo fatto il contrario (associare l’utenza al gruppo utilizzando il metodo getUserses della classe Groups) non avremmo avuto successo in quanto è la tabella Groups che comanda rispetto alla tabella Users. Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Groups g = (Groups)session.get(Groups.class,

jComboBoxGroups.getSelectedItem().toString());

Users u = (Users)session.get(Users.class, jTextUserid.getText());

Set ass = u.getGroupses();

ass.add(g);

u.setGroupses(ass);

transaction.commit();

log("Modifica avvenuta!");

} catch (HibernateException ex) {

transaction.rollback();

log("Modifica non avvenuta!");

log(ex.getMessage());

} finally {

session.close();

}

Visualizzazione delle associazioni

Ora andiamo a visualizzare le associazioni per un dato gruppo. Questo avverrà quando cliccheremo sul tasto Visualizza accanto alla tendina dei gruppi. Come noterete nel codice presente di seguito eseguiremo una query per prelevare una istanza ad un oggetto List.

Andremo quindi a scorrere questo oggetto prelevando tramite il metodo getUserses le istanze a Users associati ad esso. jTextArea.setText("");

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

List us = session.createQuery("from Groups where idGroups='" +

jComboBoxGroups.getSelectedItem().toString() + "'").list();

for (Iterator itQuery = us.iterator(); itQuery.hasNext();){

Groups g = (Groups) itQuery.next();

Set s = g.getUserses();

for (Iterator itGroups = s.iterator(); itGroups.hasNext();){

Users u = (Users) itGroups.next();

log("idUser : " + u.getIdUsers());

}

}

transaction.commit();

} catch (HibernateException ex) {

transaction.rollback();

log(ex.getMessage());

} finally {

session.close();

}

Le Annotations

Quanto visto in precedenza permette la creazione delle classi di Entità le quali saranno rappresentate da un file di configurazione nel quale saranno riportate le informazioni sulle associazioni tra le tabelle e informazioni e la tipologia dei dati rappresentati. Hibernate di fatto permette di eliminare la dipendenza dai file di configurazione introducendo il concetto di Annotazione all’interno delle classi inserendo tali informazioni sui file di configurazione all’interno delle classi che rappresentano le entità. Procediamo a creare un nuovo progetto Java con il nome HibernateAnnotations. Copiamo all’interno del progetto tutti i package creati in precedenza e presenti all’interno del progetto HibernateExampleProject. Andiamo ad importare i Jar necessari come fatto in precedenza. Ora andiamo a cancellare le classi copiate dal progetto HibernateExampleProject presenti nel package hibernate.model e cancelliamo anche i relativi files hbm in quanto procederemo ad una nuova generazione questa volta però con le annotation inserite al loro interno.

Accediamo nuovamente alle operazioni di Export di modo da aprire il Wizard di creazione automatica delle Entity.

A questo punto nel tab Main andiamo a cambiare il nome del vecchio progetto con il nuovo nel quale andremo a generare le Entity e nel tab Exporters andiamo a fleggare la voce Use Java 5 Sintax, Generate EJB3 Annotations e Domain

Code. A questo punto clicchiamo su Run e attendiamo il completamento dell’operazione.

Il plugin procederà a creare le classi all’interno del package model e questa volta saranno provviste di annotazioni, di seguito riporto la classe Users. Notiamo la presenza delle indicazioni relative alla reale colonna presente sulla tabella per ogni proprietà e se tale campo potrà essere di valore null. Inoltre nella proprietà che restituisce la collezione degli oggetti di tipo Groups saranno presente le informazioni relative all’associazione tra la tabella Users e la tabella Groups. package hibernate.model;

// Generated 11-mag-2012 8.48.33 by Hibernate Tools 3.2.4.GA

import java.util.HashSet;

import java.util.Set;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.JoinTable;

import javax.persistence.ManyToMany;

import javax.persistence.Table;

/**

* Users generated by hbm2java

*/

@Entity

@Table(name = "users", catalog = "corsojava")

public class Users implements java.io.Serializable {

private String idUsers;

private String idPassword;

private String name;

private String surname;

private Set<Groups> groupses = new HashSet<Groups>(0);

public Users() {

}

public Users(String idUsers) {

this.idUsers = idUsers;

}

public Users(String idUsers, String idPassword, String name,

String surname, Set<Groups> groupses) {

this.idUsers = idUsers;

this.idPassword = idPassword;

this.name = name;

this.surname = surname;

this.groupses = groupses;

}

@Id

@Column(name = "idUsers", unique = true, nullable = false, length = 20)

public String getIdUsers() {

return this.idUsers;

}

public void setIdUsers(String idUsers) {

this.idUsers = idUsers;

}

@Column(name = "idPassword", length = 20)

public String getIdPassword() {

return this.idPassword;

}

public void setIdPassword(String idPassword) {

this.idPassword = idPassword;

}

@Column(name = "name", length = 45)

public String getName() {

return this.name;

}

public void setName(String name) {

this.name = name;

}

@Column(name = "surname", length = 45)

public String getSurname() {

return this.surname;

}

public void setSurname(String surname) {

this.surname = surname;

}

@ManyToMany(fetch = FetchType.LAZY)

@JoinTable(name = "usersgroups", catalog = "corsojava", joinColumns = { @JoinColumn(name =

"idUsers", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name =

"idGroups", nullable = false, updatable = false) })

public Set<Groups> getGroupses() {

return this.groupses;

}

public void setGroupses(Set<Groups> groupses) {

this.groupses = groupses;

}

}

Ora prima di procedere al lancio della nostra Java Application (il codice sarà esattamente lo stesso di quello precedentemente creato nel progetto HibernateExampleProject e riportato per comodità alla fine del tutorial) dobbiamo andare a definire la SessionFactory che sarà leggermente differente rispetto alla precedente. Accediamo quindi alla classe CustomSessionFactory e andiamo ad inserire al suo interno il seguente codice. package sessionFactory;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.*;

@SuppressWarnings("deprecation")

public class CustomSessionFactory {

private static final SessionFactory sessionFactory;

static {

try {

sessionFactory = new

AnnotationConfiguration().configure().buildSessionFactory();

} catch (Throwable ex) {

System.err.println("Initial SessionFactory creation failed." + ex);

throw new ExceptionInInitializerError(ex);

}

}

public static SessionFactory getSessionFactory() {

return sessionFactory;

}

}

Come vedete cambia il tipo della classe che verrà istanziata in quanto tale classe dovrà prendere in considerazione le Annotation e leggere da queste le informazioni che prima con l’utilizzo della precedente SessionFactory venivano prelevate dai file di configurazione. A questo punto possiamo eseguire la nostra Java Application per verificare il corretto funzionamento dell’applicazione ma in questo caso saranno utilizzate le Annotation.

La sintassi HQL (Hibernate Query Language)

Riporto lo schema della base dati di esempio di modo che possano essere facilmente comprensibili gli esempi SQL o HQL che faremo di seguito.

Hibernate utilizza un linguaggio di query interno chiamato HQL, acronimo di Hibernate Query Language. In precedenza dando uno sguardo alla prospettiva Hibernate messa a disposizione dai Plugin di Hibernate abbiamo intravisto che è possibile effettuare (tramite tasto destro sulla selezione del progetto) delle query scegliendo l’opzione HQL Editor nella tendina contestuale.

Questo ci consente di visualizzare un pannello nel quale effettuare query sulle entity precedentemente generate con sintassi HQL.

Di fatto esisterà un ulteriore strato di codice che si porrà tra la nostra base dati e l’applicazione chiamato Entity Model (o Domain Model) nel quale verranno interrogate le entity a disposizione di Hibernate per generare il risultato dell’interrogazione. Ovviamente l’Entity Model utilizzerà il Data Provider per permettere l’invocazione delle API messe a disposizione dal Database e quindi interrogare il dominio relazionale.

Esempio di select in HQL

Facendo un semplice esempio, se volessimo eseguire in SQL la seguente istruzione di selezione SELECT * from Users where idUsers=’aporli’

La query in format HQL sarebbe la seguente

Select u from Users u where u.idUsers=’aporli’

E starebbe a significare, seleziona gli oggetti u di tipo Users che hanno come condizione u.idUsers=’aporli’. Ovviamente u.idUsers non è altro che il metodo set di assegnazione dell’oggetto Users.

Esempio di Join in HQL

In effetti la sintassi HQL può essere anche molto complessa e la complessità è maggiore qualora in gioco ci siano differenti Entity e collegamenti tra loro, ma questo di fatto è la stessa complessità presente nelle normali query SQL. Facendo un esempio più complesso andiamo ad effettuare il porting dall’SQL della seguente istruzione select

u.idUsers,

g.idGroups

from

corsojava.users u,

corsojava.groups g,

corsojava.usersgroups ug

where

u.idUsers = ug.idUsers and

ug.idGroups = g.idGroups

order by

g.idGroups

Che permette la visualizzazione di tutti gli utenti e i gruppi presenti nelle tabelle Users e Groups utilizzando l’associativa UsersGroups, la corrispettiva query HQL sarebbe la seguente select

u.idUsers,

g.idGroups

from

Users as u

inner join u.groupses as g

order by g.idGroups

Sicuramente in questo caso risulta più leggibile e più semplice. Facciamo uso di una inner join sul metodo u.groupses che di fatto non è altro che un contenitore delle dipendenze sull’oggetto Groups dell’oggetto Users. Il risultato tramite HQL Browser è il seguente una volta eseguito il comando.

Left e Right in SQL

A volte occorre selezionare dati da due o più tabelle per avere dei risultati completi. In questi casi occorre utilizzare la clausola Join che permette l’estrazione di questi dati presenti su diverse tabelle. Come sappiamo le tabelle in un database possono essere messe in relazione l’una con l’altra tramite il concetto di chiave. Una chiave si dice primaria quando ha un valore unico per le righe e questo valore non potrà essere ripetuto. Esistono in SQL tre tipi di Join e queste sono:

1. INNER JOIN 2. LEFT OUTER JOIN

3. RIGTH OUTER JOIN

La differenza sta nella modalità con cui verrà mostrato l’output della selezione e di come verranno unite le tabelle in fase di esecuzione della query. Inner Join La clausola Inner Join restituisce le righe delle tabelle se c'è un legame effettivo, in caso contrario non mostra nulla. select

u.idUsers,

ug.idGroups

from

corsojava.users u

inner join

corsojava.usersgroups ug

on

u.idUsers = ug.idUsers order by

u.idUsers

Il risultato della query

Left outer join La clausola Left outer join abbreviata anche in left join restituisce tutte le righe della prima tabella (nel nostro caso gli utenti), anche se non ci sono select

u.idUsers,

ug.idGroups

from

corsojava.users u

left join

corsojava.usersgroups ug

on

u.idUsers = ug.idUsers order by

u.idUsers

Il risultato della Query

Right outer join La clausola Right outer join abbreviata anche in right join restituisce tutte le righe della seconda tabella (nel nostro caso gli utenti), anche se non ci sono select

u.idUsers,

ug.idGroups

from

corsojava.users u

right join

corsojava.usersgroups ug

on

u.idUsers = ug.idUsers order by

u.idUsers

Come potete vedere in questo caso il risultato della Query sarà identico al risultato dell’inner join in quanto la tabella usersgroups è una tabella associativa tra due tabelle Users e Groups.

In una classica tabella associativa (Chiave, Descrizione) come ad esempio Utenti e comuni come riportato qua sotto

Il risultato della Right Join riportata in calce select

u.idUsers,

c.comune

from

anagrafica.utenti u

right join

anagrafica.comuni c

on

u.comune = c.comune

order by

c.comune

E’ il seguente ovvero sarebbero state visualizzate tutte le occorrenze presenti nella tabella utenti con le associazioni alla tabella comuni e in più tutte le occorrenze che non hanno relazione con la tabella utenti.

Left e Right in HQL

Di fatto una volta spiegato il funzionamento delle clausole left e right join in SQL il concetto non cambia in HQL.

Se prendiamo di fatto l’esempio fatto in precedenza sulla JOIN e andiamo ad inserire al suo interno la clausola left (right nel caso delle nostre entity riporterà un valore identico alla inner join) avremo il seguente risultato.

E’ importante conoscere in HQL il concetto di left outer join e right outer join. Tale sintassi può essere abbreviata in left join o right join. Per ulteriori delucidazioni sulla sintassi HQL vi rimando ai link della documentazione di Hibernate http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html Dove sono riportati numerosi esempi su interrogazioni HQL. Nota Bene : In relazione ad altri ORM possiamo dire che Hibernate di fatto non compila la sintassi del codice HQL in quanto tale codice è passato come stringa al metodo createQuery() della sessione. In ADO.NET Entity Framework il linguaggio di interrogazione delle entità corrispettivo di HQL è LINQ to Entity Framework, questo linguaggio è annidato all’interno del RAD Visual Studio e viene compilato insieme al codice demandando al programmatore solo la logica di interrogazione e non la sua sintassi.

Utilizzo di SQL Nativo in Hibernate

Come retrocompatibilità, con Hibernate è possibile eseguire delle query con la vecchia sintassi SQL utilizzando il metodo createSQLQuery messo a disposizione dalla sessionFactory. Da tenere in considerazione che createSQLQuery è diverso da createQuery metodo che permette di invocare query scritte in HQL. L’esempio riportato di seguito visualizza tutte le utenze presenti nella tabella Users specificando l’istruzione SQL SELECT * from Users order by idusers desc. In questo modo verrà generato un oggetto Query il quale metterà a disposizione il metodo list() che restituirà una lista di oggetti nel mio caso Users. A questo punto scorreremo la lista tramite il metodo iterator() come fatto in precedenza. Session session = CustomSessionFactory.getSessionFactory().openSession();

Query query = session.createSQLQuery("SELECT * from Users order by idusers

desc").addEntity(Users.class);

List <Users> list = query.list();

for (Iterator iterator = list.iterator(); iterator.hasNext();){

Users u = (Users) iterator.next();

log("idUser : " + u.getIdUsers());

log("idPassword : " + u.getIdPassword());

log("Name : " + u.getName());

log("Surname : " + u.getSurname());

}

session.close();

Il codice completo dell’Applet Swing

Per facilità d’uso riporto il codice completo dell’Applet utilizzata come test per questa dispensa. package userInterface;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.Transaction;

import org.hibernate.Query.*;

import hibernate.model.*;

import javax.swing.*;

import sessionFactory.CustomSessionFactory;

import java.awt.Dimension;

import java.awt.Rectangle;

import java.util.Iterator;

import java.util.List;

import java.util.Set;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JComboBox;

public class TestHibernate extends JFrame {

private static final long serialVersionUID = 1L;

private JPanel jContentPane = null;

private JLabel jLabel = null;

private JLabel jLabel1 = null;

private JTextArea jTextArea = null;

private JTextField jTextSurname = null;

private JLabel jLabel2 = null;

private JLabel jLabel3 = null;

private JTextField jTextUserid = null;

private JTextField jTextPassword = null;

private JTextField jTextName = null;

private JScrollPane jScrollPane = null;

private JButton jButtonSearch = null;

private JButton jButtonChange = null;

private JButton jButtonDelete = null;

private JLabel jLabel4 = null;

private JComboBox jComboBoxGroups = null;

private JButton jButtonInsert = null;

private JButton jButtonAssociate = null;

private JButton jButtonViewGroups = null;

private JTextArea getJTextArea() {

if (jTextArea == null) {

jTextArea = new JTextArea();

}

return jTextArea;

}

private JTextField getJTextSurname() {

if (jTextSurname == null) {

jTextSurname = new JTextField();

jTextSurname.setBounds(new Rectangle(106, 58, 360, 16));

}

return jTextSurname;

}

private JTextField getJTextUserid() {

if (jTextUserid == null) {

jTextUserid = new JTextField();

jTextUserid.setBounds(new Rectangle(106, 15, 106, 16));

}

return jTextUserid;

}

private JTextField getJTextPassword() {

if (jTextPassword == null) {

jTextPassword = new JTextField();

jTextPassword.setBounds(new Rectangle(314, 15, 151, 16));

}

return jTextPassword;

}

private JTextField getJTextName() {

if (jTextName == null) {

jTextName = new JTextField();

jTextName.setBounds(new Rectangle(106, 37, 360, 16));

}

return jTextName;

}

private JScrollPane getJScrollPane() {

if (jScrollPane == null) {

jScrollPane = new JScrollPane();

jScrollPane.setBounds(new Rectangle(15, 100, 455, 127));

jScrollPane.setViewportView(getJTextArea());

}

return jScrollPane;

}

public TestHibernate() {

super();

initialize();

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

List gr = session.createQuery("from Groups").list();

for (Iterator iterator = gr.iterator(); iterator.hasNext();){

Groups g = (Groups) iterator.next();

jComboBoxGroups.addItem(g.getIdGroups());

}

transaction.commit();

} catch (HibernateException ex) {

transaction.rollback();

log("Inserimento non avvenuto!");

log(ex.getMessage());

} finally {

session.close();

}

}

private void initialize() {

this.setSize(490, 291);

this.setContentPane(getJContentPane());

this.setTitle("JFrame");

}

private void log(String value){

jTextArea.setText(jTextArea.getText() + "\n" + value);

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jLabel4 = new JLabel();

jLabel4.setBounds(new Rectangle(16, 78, 77, 16));

jLabel4.setText("Gruppo :");

jLabel3 = new JLabel();

jLabel3.setBounds(new Rectangle(16, 58, 79, 16));

jLabel3.setText("Cognome :");

jLabel2 = new JLabel();

jLabel2.setBounds(new Rectangle(16, 37, 76, 16));

jLabel2.setText("Nome :");

jLabel1 = new JLabel();

jLabel1.setBounds(new Rectangle(224, 15, 80, 16));

jLabel1.setText("Password : ");

jLabel = new JLabel();

jLabel.setBounds(new Rectangle(16, 15, 81, 16));

jLabel.setText("User id :");

jContentPane = new JPanel();

jContentPane.setLayout(null);

jContentPane.add(jLabel, null);

jContentPane.add(jLabel1, null);

jContentPane.add(getJTextSurname(), null);

jContentPane.add(jLabel2, null);

jContentPane.add(jLabel3, null);

jContentPane.add(getJTextUserid(), null);

jContentPane.add(getJTextPassword(), null);

jContentPane.add(getJTextName(), null);

jContentPane.add(getJScrollPane(), null);

jContentPane.add(getJButtonSearch(), null);

jContentPane.add(getJButtonChange(), null);

jContentPane.add(getJButtonDelete(), null);

jContentPane.add(jLabel4, null);

jContentPane.add(getJComboBoxGroups(), null);

jContentPane.add(getJButtonInsert(), null);

jContentPane.add(getJButtonAssociate(), null);

jContentPane.add(getJButtonViewGroups(), null);

}

return jContentPane;

}

private JButton getJButtonSearch() {

if (jButtonSearch == null) {

jButtonSearch = new JButton();

jButtonSearch.setBounds(new Rectangle(136, 231, 93, 26));

jButtonSearch.setText("Ricerca");

jButtonSearch.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

System.out.println("mouseClicked()"); // TODO Auto-generated Event stub mouseClicked()

String textFind = jTextUserid.getText();

jTextArea.setText("");

jTextUserid.setText("");

jTextPassword.setText("");

jTextName.setText("");

jTextSurname.setText("");

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

List us = session.createQuery("from Users").list();

for (Iterator iterator = us.iterator(); iterator.hasNext();){

Users u = (Users) iterator.next();

if (textFind.equals(u.getIdUsers())){

jTextUserid.setText(u.getIdUsers());

jTextPassword.setText(u.getIdPassword());

jTextName.setText(u.getName());

jTextSurname.setText(u.getSurname());

}

log("idUser : " + u.getIdUsers());

log("idPassword : " + u.getIdPassword());

log("Name : " + u.getName());

log("Surname : " + u.getSurname());

}

transaction.commit();

} catch (HibernateException ex) {

transaction.rollback();

log("Inserimento non avvenuto!");

log(ex.getMessage());

} finally {

session.close();

}

}

});

}

return jButtonSearch;

}

private JButton getJButtonChange() {

if (jButtonChange == null) {

jButtonChange = new JButton();

jButtonChange.setBounds(new Rectangle(251, 231, 97, 26));

jButtonChange.setText("Modifica");

jButtonChange.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Users u = (Users) session.get(Users.class, jTextUserid.getText());

u.setIdPassword(jTextPassword.getText());

u.setName(jTextName.getText());

u.setSurname(jTextSurname.getText());

transaction.commit();

log("Modifica avvenuta!");

} catch (HibernateException ex) {

transaction.rollback();

log("Modifica non avvenuta!");

log(ex.getMessage());

} finally {

session.close();

}

}

});

}

return jButtonChange;

}

private JButton getJButtonDelete() {

if (jButtonDelete == null) {

jButtonDelete = new JButton();

jButtonDelete.setBounds(new Rectangle(370, 231, 98, 26));

jButtonDelete.setText("Cancella");

jButtonDelete.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Users u = (Users) session.get(Users.class, jTextUserid.getText());

session.delete(u);

transaction.commit();

log("Modifica avvenuta!");

} catch (HibernateException ex) {

transaction.rollback();

log("Modifica non avvenuta!");

log(ex.getMessage());

} finally {

session.close();

}

}

});

}

return jButtonDelete;

}

private JComboBox getJComboBoxGroups() {

if (jComboBoxGroups == null) {

jComboBoxGroups = new JComboBox();

jComboBoxGroups.setBounds(new Rectangle(106, 78, 137, 16));

}

return jComboBoxGroups;

}

private JButton getJButtonInsert() {

if (jButtonInsert == null) {

jButtonInsert = new JButton();

jButtonInsert.setBounds(new Rectangle(16, 231, 98, 26));

jButtonInsert.setText("Inserisci");

jButtonInsert.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Users u = new Users();

u.setIdUsers(jTextUserid.getText());

u.setIdPassword(jTextPassword.getText());

u.setName(jTextName.getText());

u.setSurname(jTextSurname.getText());

session.save(u);

transaction.commit();

log("Inserimento avvenuto!");

} catch (HibernateException ex) {

transaction.rollback();

log("Inserimento non avvenuto!");

log(ex.getMessage());

} finally {

session.close();

}

}

});

}

return jButtonInsert;

}

private JButton getJButtonAssociate() {

if (jButtonAssociate == null) {

jButtonAssociate = new JButton();

jButtonAssociate.setBounds(new Rectangle(247, 78, 114, 17));

jButtonAssociate.setText("Associa");

jButtonAssociate.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Groups g = (Groups)session.get(Groups.class,

jComboBoxGroups.getSelectedItem().toString());

Users u = (Users)session.get(Users.class, jTextUserid.getText());

Set ass = u.getGroupses();

ass.add(g);

u.setGroupses(ass);

transaction.commit();

log("Modifica avvenuta!");

} catch (HibernateException ex) {

transaction.rollback();

log("Modifica non avvenuta!");

log(ex.getMessage());

} finally {

session.close();

}

}

});

}

return jButtonAssociate;

}

/**

* This method initializes jButtonViewGroups

*

* @return javax.swing.JButton

*/

private JButton getJButtonViewGroups() {

if (jButtonViewGroups == null) {

jButtonViewGroups = new JButton();

jButtonViewGroups.setBounds(new Rectangle(362, 78, 105, 17));

jButtonViewGroups.setText("Visualizza");

jButtonViewGroups.addMouseListener(new java.awt.event.MouseAdapter() {

public void mouseClicked(java.awt.event.MouseEvent e) {

jTextArea.setText("");

Session session = CustomSessionFactory.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

List us = session.createQuery("from Groups where idGroups='" +

jComboBoxGroups.getSelectedItem().toString() + "'").list();

for (Iterator itQuery = us.iterator(); itQuery.hasNext();){

Groups g = (Groups) itQuery.next();

Set s = g.getUserses();

for (Iterator itGroups = s.iterator(); itGroups.hasNext();){

Users u = (Users) itGroups.next();

log("idUser : " + u.getIdUsers());

}

}

transaction.commit();

} catch (HibernateException ex) {

transaction.rollback();

log(ex.getMessage());

} finally {

session.close();

}

}

});

}

return jButtonViewGroups;

}

} // @jve:decl-index=0:visual-constraint="10,10"

Bibliografia

http://www.electrictoolbox.com/mysqldump-schema-only/ http://www.wikihow.com/Generate-Hibernate-Pojo-Classes-from-DB-Tables http://docs.jboss.org/tools/3.0.1.GA/en/hibernatetools/html_single/index.html http://www.laliluna.de/articles/java-persistence-hibernate/first-hibernate-example-tutorial.html http://www.vaannila.com/hibernate/hibernate-example/hibernate-tools-1.html