Programmazione Java Avanzata



Documenti analoghi
Il linguaggio SQL. è di fatto lo standard tra i linguaggi per la gestione di data base relazionali.

User Tools: DataBase Manager

Capitolo 13. Interrogare una base di dati

Abilità Informatiche A.A. 2010/2011 Lezione 9: Query Maschere Report. Facoltà di Lingue e Letterature Straniere

Basi di dati. Il Linguaggio SQL. K. Donno - Il Linguaggio SQL

Volumi di riferimento

Dispensa di database Access

Concetti fondamentali dei database database Cos'è un database Principali database

I DATABASE Database relazionale

Data Base. Master "Bio Info" Reti e Basi di Dati Lezione 6

Sistemi Mobili e Wireless Android - Dati persistenti: SQLite

Insegnamento di Informatica CdS Scienze Giuridiche A.A. 2006/7. Il trattamento dei dati

Modulo 4: Ereditarietà, interfacce e clonazione

Esercizio data base "Biblioteca"

DDL, VINCOLI D INTEGRITÁ, AGGIORNAMENTI E VISTE. SQL è più di un semplice linguaggio di interrogazione

Corso Sistemi Informativi Avanzati. Programma 30 set Installazione Macchina Virtuale. Introduzione alla BI nelle Aziende.

Database Lezione 1. Sommario. - Introduzione - Tabelle e chiave primaria - Query - Calcoli ed alias - Ordinamento

Utilizzando Microsoft Access. Si crea la tabella Anagrafica degli alunni,le Materie e i voti si mettono alcuni campi

Esercitazione query in SQL L esercitazione viene effettuata sul database viaggi e vacanze che prevede il seguente modello E/R:

SQL SQL. Definizione dei dati. Domini. Esistono 6 domini elementari:

Database 1 biblioteca universitaria. Testo del quesito

I database relazionali sono il tipo di database attualmente piu diffuso. I motivi di questo successo sono fondamentalmente due:

Corso su LINQ Lezione 16. Introduzione

Mon Ami 3000 Varianti articolo Gestione di varianti articoli

5.2.1 RELAZIONI TRA TABELLE Creare una relazione uno-a-uno, uno-a-molti tra tabelle 9

Operazioni sui database

Come modificare la propria Home Page e gli elementi correlati

DBMS (Data Base Management System)

OSSIF WEB. Manuale query builder

Manuale Amministratore Legalmail Enterprise. Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise

Organizzazione degli archivi

SISTEMI INFORMATIVI AVANZATI -2010/ Introduzione

GERARCHIE RICORSIVE - SQL SERVER 2008

SQL: concetti base SQL. Definizione dei dati in SQL. SQL: "storia"

ESEMPI DI QUERY SQL. Esempi di Query SQL Michele Batocchi AS 2012/2013 Pagina 1 di 7

Informatica Generale Andrea Corradini Sistemi di Gestione delle Basi di Dati

Al giorno d oggi, i sistemi per la gestione di database

Definizione di domini

MySQL Database Management System

Introduzione ai database relazionali

Introduzione alla teoria dei database relazionali. Come progettare un database

Riccardo Dutto, Paolo Garza Politecnico di Torino. Riccardo Dutto, Paolo Garza Politecnico di Torino

MySQL Database Management System

SQL. Alcune note sulla definizione dei dati

TEORIA sulle BASI DI DATI

MANUALE PARCELLA FACILE PLUS INDICE

I comandi del linguaggio DDL (Data Definition Language): CREATE E ALTER

Si formulino le seguenti interrogazioni tramite il linguaggio SQL:

Airone Gestione Rifiuti Funzioni di Esportazione e Importazione

19. LA PROGRAMMAZIONE LATO SERVER

Basi di Dati e Microsoft Access

Progetto NoiPA per la gestione giuridicoeconomica del personale delle Aziende e degli Enti del Servizio Sanitario della Regione Lazio

ARCHIVI E DATABASE (prof. Ivaldi Giuliano)

SQL Server Introduzione all uso di SQL Server e utilizzo delle opzioni Olap. Dutto Riccardo - SQL Server 2005.

Guida all uso di Java Diagrammi ER

Manuale Utente Albo Pretorio GA

Regione Toscana. ARPA Fonte Dati. Manuale Amministratore. L. Folchi (TAI) Redatto da

ECDL - Database. European Computer Driving Licence - Modulo 5 - Database LEZIONE 2

IL DAT A B A S E DI ALGE B R A N D O

CORSO ACCESS PARTE II. Esistono diversi tipi di aiuto forniti con Access, generalmente accessibili tramite la barra dei menu (?)

SQL prima parte D O C E N T E P R O F. A L B E R T O B E L U S S I. Anno accademico 2011/12

Database. Si ringrazia Marco Bertini per le slides

Strutturazione logica dei dati: i file

INDICI. Prevediamo di effettuare spesso interrogazioni simili alle seguenti:

Giovanna Rosone 04/03/ /03/2010 SQL, Istruzioni per la modifica dello schema

SQL/OLAP. Estensioni OLAP in SQL

SQL -DDL. FONDISTA(Nome, Nazione, Età) GAREGGIA(NomeFondista, NomeGara, Piazzamento) GARA(Nome, Luogo, Nazione, Lunghezza)

Siti web centrati sui dati Architettura MVC-2: i JavaBeans

CONTENT MANAGEMENT SY STEM

Le query di raggruppamento

Corso sul linguaggio SQL

Progetto: ARPA Fonte Dati. ARPA Fonte Dati. Regione Toscana. Manuale Amministratore

Sviluppata da: Lo Russo - Porcelli Pag. 1 di 6 6FRSR utilizzare il DBMS Postgresql per imparare il linguaggio SQL.

Lezione V. Aula Multimediale - sabato 29/03/2008

Soluzione dell esercizio del 2 Febbraio 2004

Microsoft Access. Microsoft Access

PRODUZIONE PAGELLE IN FORMATO PDF

Programmazione a Oggetti Modulo B

Funzioni non documentate Openoffice.org. 3 Base mini-howto

Architettura MVC-2: i JavaBeans

Microsoft Access 2000

GCEWEB Denunce mensili in WEB

Basi di Dati: Corso di laboratorio

Access. P a r t e p r i m a

SOSEBI PAPERMAP2 MODULO WEB MANUALE DELL UTENTE

I file di dati. Unità didattica D1 1

Facoltà di Farmacia - Corso di Informatica

Manuale utente Volta Control

Il linguaggio SQL: query innestate

Costruzione del layout in gino cms

NUOVO SISTEMA AGGIORNAMENTO DA FYO

Esercitazione di Basi di Dati

Iniziamo la panoramica sul funzionamento dell'svn sulla suite S.A.

Settaggio impostazioni tema. Cliccando nuovamente su aspetto e poi su personalizza si avrà modo di configurare la struttura dinamica della template.

SQL (STRUCTURED QUERY LANGUAGE)

C A T A L O G O. Catalogo del Sistema Bibliotecario Padovano. Gruppo Lavoro per il Coordinamento dei Corsi all Utenza

DATABASE RELAZIONALI

INFORMATICA. Applicazioni WEB a tre livelli con approfondimento della loro manutenzione e memorizzazione dati e del DATABASE.

Per chi ha la Virtual Machine: avviare Grass da terminale, andando su Applicazioni Accessori Terminale e scrivere grass

Scenari esemplificativi di utilizzo delle Mailing List

Transcript:

Programmazione Java Avanzata Hibernate (Parte 2) Ing. Giuseppe D'Aquì

Testi Consigliati Beginning Hibernate 2 nd edition (Apress) Sul sito è possibile scaricare, tra gli extra, il codice sorgente e il capitolo 3 Hibernate Getting Started http://docs.jboss.org/hibernate/core/3.6/quickstart/e 2

Pro e contro Annotations Pro: Le annotation sono standard JPA, quindi sono usate in modo identico da tutti gli ORM JPA-compatibili Meno verbosità Intuitive Contro: Le versioni obsolete di Hibernate supportano solo XML Se il database è usato da più applicazioni, si rischia di distribuire il mapping su applicazioni diverse 3

Chiave Composta Se in una tabella la chiave primaria è costituita da più campi, si ha una chiave composta Quando non ci sono particolari vincoli (ovvero abbiamo il controllo dello schema del database), in genere si preferisce semplificare lo sviluppo generando una chiave surrogata Una chiave surrogata non ha significato al di fuori del database, è un campo che rimpiazza i molti campi della chiave composta 4

Chiave Composta Quando però ci sono vincoli la chiave composta deve essere mappata su Hibernate Ci sono tre modalità, tutte e tre prevedono la creazione di una classe che contenga il mapping dei campi della chiave composta Es. se la chiave composta è (nome, cognome), allora serve una classe (differente dalla corrente) che contenga come variabili membro String nome e String cognome 5

Chiave composta: modo 1 La classe con gli attributi chiave deve essere pubblica ed esterna public class UserPrimaryKey{...} La classe va annotata con @Embeddable, e devono essere implementati i metodi hashcode() ed equals() Nella classe originaria, invece, bisogna sostituire gli attributi della chiave composta con un unica variabile id (annotata con @Id) private UserPrimaryKey id; 6

Chiave composta: modo 2 La classe con gli attributi chiave va creata come nel modo 1, ma internamente alla classe originaria La classe non va annotata con @Embeddable La classe originaria ha sempre la variabile id ma annotata con @EmbeddedId 7

Chiave composta: modo 3 La classe con gli attributi chiave va creata come nel modo 2 Si annota solo la classe originaria con @IdClass Passandogli la classe che fa le funzioni di chiave @IdClass(User.UserPrimaryKey.class) Nella classe originaria non c'è più id ma vanno messi gli attributi originali annotati con @Id 8

Chiave composta: riassunto Il codice SQL generato in tutti i casi è uguale Ci sono particolarità di utilizzo: Modo 1: La classe con gli attributi è esterna ed embeddable (vedi relazioni one-to-one), può essere riutilizzata Modo 3: possiamo utilizzare gli attributi chiave direttamente dalla classe originaria [getnome() e getcognome()], invece di ottenere prima l'oggetto id Modo 2: una via di mezzo 9

Mapping di relazioni Le relazioni tra tabelle possono essere di diverso tipo One-to-One (uno-a-uno) One-to-Many (uno-a-molti) Many-to-Many (molti-a-molti) 10

One-to-one: tipi Le relazioni uno-a-uno, in Hibernate, sono di due tipi: Classiche, due tabelle corrispondono a due oggetti Component o embedded, due oggetti che risiedono su una sola tabella (es. l'indirizzo) 11

One-to-one embedded Una relazione one-to-one embedded si ha quando un'entità è interamente racchiusa all'interno di un'altra entità, ossia è un componente dell'alltra entità La classe componente va annotata con @Embeddable, non possiede @Id Nella classe principale viene posta una variabile membro con lo stesso tipo della classe componente, annotata con @Embedded 12

One-to-one embedded public class User { } @Embedded public Address getaddress(){...} @Embeddable public class Address{ } private String via; private String civico; //getters/setters 13

One-to-one La relazione uno-a-uno convenzionale è in genere sospetta, perché potrebbe nascondere un errore di progettazione In genere, infatti, si tende ad accorpare tutti gli attributi in una sola entità Ci sono dei casi in cui, però, è preferibile avere due tabelle che rappresentano due aspetti differenti di una certa entità ideale Aspetti che devono essere gestiti differentemente, o che devono evolvere in modo indipendente Es. Profilo Autenticazione e Anagrafiche 14

One-to-one Per mappare una relazione uno-a-uno basta annotare con @OneToOne la variabile membro (o il getter) che contiene l'oggetto correlato 15

One-to-one classica public class User { @OneToOne public Address getaddress(){...} } @Entity public class Address{ @Id private int id; private String via; private String civico; } //getters/setters 16

One-to-one L'annotazione @OneToOne può avere i seguenti attributi: cascade: indica se le operazioni su una entità devono propagarsi alle altre della relazione fetch: indica il tipo di acquisizione, eager (carica tutti gli oggetti del grafo delle relazioni) o lazy (carica gli oggetti correlati solo se servono) optional: serve per stabilire se ci possono essere NULL 17

One-to-one bidirezionale La relazione OneToOne è bidirezionale quando l'oggetto A contiene un riferimento all'oggetto B, e l'oggetto B contiene un riferimento all'oggetto A Es. User.getAddress() e Address.getUser() In questo caso uno dei due oggetti deve essere considerato principale Quello la cui tabella contiene la chiave primaria dell'altro come riferimento L'oggetto secondario dovrà usare l'attributo mappedby nella sua annotazione @OneToOne 18

One-to-one bidirezionale @Entity public class User { //User è l'oggetto principale @OneToOne public Address getaddress(){...} } @Entity public class Address{ //Address è l'oggetto secondario //il mappedby si riferisce alla proprietà dell'oggetto principale @OneToOne(mappedBy=address) } public User getuser(){...} 19

One-to-one - JoinColumn Per default, Hibernate cercherà come foreign key un campo della tabella con queste caratteristiche: Inizia con il nome della proprietà dell'oggetto principale (User ha getaddress(), quindi address ) Concatenato con underscore _ Concatenato con il nome della chiave primaria dell'oggetto secondario (Es, Address ha getid(), quindi id Nell'esempio quindi cercherà una colonna chiamata address_id 20

One-to-one - JoinColumn È possibile sovrascrivere questo default con due tipi di annotazioni: @PrimaryKeyJoinColumn : usato assieme a @OneToOne sull'oggetto principale, indica che la foreign key è la stessa chiave primaria (ovvero, le due tabelle possiedono la stessa chiave primaria) @JoinColumn(name= address_fk ) : usato assieme a @OneToOne sull'oggetto principale, indica che la foreign key sta in una colonna con un nome preciso (in questo caso address_fk ) 21

Cascading delle operazioni Il cascading è la propagazione delle operazioni di aggiornamento e rimozione su oggetti collegati tra loro da relazioni Esempio: se viene cancellato un User deve essere cancellato il corrispondente Address? Hibernate definisce diversi tipi di cascading, definiti nelle relazioni Se non si specifica niente, per default non si ha cascading 22

Cascading delle operazioni Tipi di cascading: CascadeType.MERGE : propaga gli UPDATE CascadeType.PERSIST : propaga il primo inserimento (INSERT) CascadeType.REFRESH : propaga l'aggiornamento dal database verso gli oggetti (SELECT) CascadeType.DETACH : propaga la rimozione dell'oggetto dalla persistenza CascadeType.REMOVE : propaga la rimozione dei dati dell'oggetto (DELETE) CascadeType.ALL : tutti i precedenti 23

One-to-Many La relazione uno-a-molti può essere vista da due prospettive diverse L'oggetto A ha una relazione con molti oggetti B Ogni oggetto B ha una relazione con uno e un solo oggetto A Hibernate mappa queste due prospettive usando @OneToMany e @ManyToOne 24

One-to-Many @OneToMany va sull'oggetto che contiene @ManyToOne va sull'oggetto contenuto JPA considera, per convezione, oggetto principale quello che ha @ManyToOne che, quindi, dovrà specificare un mappedby 25

One-to-Many @Entity public class User { //User è l'oggetto secondario @OneToMany(mappedBy= user ) public Set<Telephone> gettelephone(){...} } @Entity public class Telephone{ //Telephone è l'oggetto principale @ManyToOne public User getuser(){...} } 26

One-to-Many - JoinColumn Valgono le stesse considerazioni di JoinColumn fatte nel caso One-to-One Nell'esempio Hibernate cercherà una colonna chiamata user_id nella tabella telephone (oggetto principale) Possiamo però specificare un'altra colonna utilizzando @JoinColumn insieme a @ManyToOne nell'oggetto principale 27

Ordering Quando vengono mappate delle Collection, possiamo definire una colonna sulla quale queste verranno ordinate @OneToMany(mappedBy= user ) public List<Telephone> gettelephone(){...} //List è un tipo collection ordinato Si può aggiungere a @OneToMany l'annotazione @OrderBy, che permette di specificare quale proprietà di Telephone usare per l'ordinamento @OneToMany(mappedBy user ) @OrderBy( prefisso ASC ) public List<Telephone> gettelephone(){...} 28

Many-to-Many In una relazione Many-to-Many entrambi gli oggetti coinvolti utilizzeranno @ManyToMany Uno dei due deve essere l'oggetto principale, l'altro conterrà l'attributo mappedby Una relazione molti-a-molti nel modello relazionale ha bisogno di una tabella ausiliaria che contiene le foreign key di entrambe le tabelle 29

Many-to-Many La tabella ausiliaria ha, per default, il nome: Tabellaprincipale_Tabellasecondaria E chiavi Tabellaprincipale_id e Tabellasecondaria_id Questi default possono essere sovrascritti con @JoinTable, usato lato oggetto principale @JoinTable( name= studenti_e_corsi, joincolumns={@joincolumn(name= corso_id )}, inversejoincolumns{@joincolumn(name= matricola )} ) 30

Many-to-Many: nota bene Quando c'è una relazione molti-a-molti che contiene attributi specifici, forse non si tratta di una mera relazione tra tabelle ma è una entità di fatto Es. se la tabella Studente_Corso contiene l'attributo voto, non è più una semplice tabella di join ma un'entità Esame, che ha relazioni uno-a-molti con Studente e con Corso La tabella di join, per Hibernate, contiene solo le foreign key e non altri attributi 31

Ereditarietà L'ereditarietà in Hibernate e JPA può essere rappresentata in tre modi: Single table: una singola tabella che contiene padri e figli Joined: una tabella per il padre e una per ciascuno dei figli, ma i figli contengono solo gli attributi non in comune con il padre Table-per-class: tabelle complete per ogni figlio 32

Ereditarietà: single table Single table prevede una singola tabella per i padri e per i figli Una singola tabella contiene più specializzazioni di una stessa entità base: gli attributi di un figlio non avranno senso nel caso di un fratello (e saranno quindi NULL) La strategia single table si usa annotando la classe padre con @Inheritance(strategy= SINGLE_TABLE) 33

Ereditarietà: single table Quando si usa una singola tabella per tutta la gerarchia, bisogna specificare una colonna discriminante che contiene informazioni sul tipo dell'oggetto Si aggiunge @DiscriminatorColumn nelle annotazioni della classe padre @Entity @DiscriminatorColumn(name= tipologia ) public class Padre {...} 34

Ereditarietà: single table Per default Hibernate, come discriminante, crea/cerca una colonna chiamata DTYPE di tipo stringa Questo default può essere sovrascritto: discriminatortype: può essere DiscriminatorType.STRING DiscriminatorType.CHAR DiscriminatorType.INTEGER lenght: la lunghezza del campo, usata solo nel caso stringa 35

Ereditarietà: single table I valori contenuti nella colonna discriminante sono, per default, i nomi delle classi figlio Volendo usare valori differenti si dovranno annotare le classi figlio con @DiscriminatorValue( valore ) 36

Ereditarietà: Joined Le annotazioni sono identiche al caso Single Table C'è @DiscriminatorColumn, @DiscriminatorValue eccetera Si attua annotando la classe padre con @Inheritance(strategy = JOINED) A basso livello Hibernate creerà/cercherà una tabella per il padre......e una tabella per ogni figlio, che conterrà soltanto gli attributi che non sono già presenti nel padre 37

Ereditarietà: Table Per Class Con questa strategia, tutti gli oggetti (padre e figli), se concreti, avranno tabelle che contengono tutti i loro attributi Basta annotare la classe padre con @Inheritance(strategy = TABLE_PER_CLASS) 38

Ereditarietà: Quale Strategia? Usando Joined si avrà uno schema più mantenibile, perchè ogni modifica di un figlio impatta solo sulla tabella del figlio, e ogni modifica al padre impatta solo sulla tabella padre Usando table-per-class, ogni modifica al padre impatterà anche su tutte le tabelle dei figli mentre le performance sono migliori del caso Joined, perché non ci sono join Single Table ha migliori performance, perché tutte le query vengono fatte su una sola tabella, ma può diventare disordinata 39

Mapped Superclass Un caso speciale di ereditarietà si ha quando la classe padre non è resa persistente e quindi, in teoria, non dovrebbe possedere annotazioni Hibernate In realtà per far funzionare l'ereditarietà dovremo annotare la classe padre come se fosse persistente, e poi aggiungere @MappedSuperClass Subito dopo @Entity, per specificare che la classe padre è solo mappata e non deve essere resa persistente 40

Altre annotazioni 41

Dati temporali Le proprietà di tipo java.util.date vengono di default mappate su attributi di tipo TIMESTAMP Questo comportamento può essere modificato con l'annotazione @Temporal @Temporal(TemporalType.DATE) @Temporal(TemporalType.TIME) @Temporal(TemporalType.TIMESTAMP) 42

Large Objects I Large Objects sono attributi di una tabella che contengono oggetti molto grandi: stringhe estese (LONGTEXT) sequenze di byte (BLOB, Binary Large OBject) Per specificare che una certa proprietà va salvata in un attributo di tipo large, basta annotarla con @Lob @Lob public String gettitle() { } Si creerà un attributo che non sarà varchar 43

Generare Indici Questa è una annotazione non inclusa in JPA, solo in Hibernate Gli indici possono essere applicati: Alla singola colonna, con l'annotazione @Index(name= nomedellindice ) Su diverse colonne contemponaneamente, annotando la classe con: @Table(appliesTo= nometabella, indexes = { }) @Index(name= nomeindice1, columnnames={ col1, col2 } 44

Named Query Una Named Query è una query (in HQL) a cui diamo un nome, per poter essere richiamata successivamente È composta quindi da una coppia (nome, espressione) Si definisce con annotazione di classe: @Entity @NamedQuery(name= findallstudents, query= from Students ) public class Student{ } 45

Named Query La caratteristica delle Named Query è quella di essere riutilizzabili Se vogliamo riutilizzarle tra più classi, dobbiamo definirle a livello di package Si crea un file chiamato package-info.java che conterrà le annotazioni che devono essere condivise tra tutte le classi del package @NamedQuery(name= findallstudents, query= from Students ) package it.unirc.pja.example2 46

Hibernate Console 47

Hibernate Console La Hibernate Console è un tool che fa parte del plugin per Eclipse Permette di svolgere le seguenti funzioni Visualizzazione rapida dei mapping e degli schemi Scrittura di query di test HQL (parametrizzate e non) Generazione dello schema del database a partire dai mapping Generazione di diagrammi che rappresentano i mapping 48

Hibernate console: esempio Vedi 49

Metodi base di Session 50

Metodi base di Session Abbiamo già visto che l'oggetto Session è fondamentale Svolge la funzione di interfaccia tra i nostri oggetti Java e Hibernate Session ha un certo numero di metodi utilizzati per richiamare le funzionalità di Hibernate 51

Salvataggio Quando si crea un nuovo oggetto che possiede mapping Hibernate, questo non viene automaticamente reso persistente Si deve salvare per la prima volta in una Session, tramite il metodo save() session.save(oggetto); 52

Nota Bene: Confronto Un certo oggetto reso persistente avrà due modi per essere identificato: Identificativo di istanza della classe (che rappresenta l'oggetto) Chiave primaria (che rappresenta la tupla) Nell'ambito di una stessa sessione entrambi gli identificativi potranno essere usati, mentre su più sessioni l'identificativo di istanza potrebbe cambiare Bisogna quindi evitare di usare l'operatore == (che confronta l'identificativo di istanza); meglio usare equals(), magari implementata da noi con il confronto tra le primary key 53

Caricamento Il caricamento di oggetti persistenti avviene tramite load() Ha due parametri: La classe della entity, passata come nome (String) o come oggetto Class L'id dell'oggetto (chiave primaria) Se la chiave specificata non esiste verrà lanciata una eccezione Simile a load() è get(): se la chiave non esiste restituisce NULL invece di una eccezione 54

Caricamento: Lock modes Sia load() che get() supportano un terzo parametro, opzionale, che serve a specificare il lock degli oggetti caricati Il lock è usato per evitare problemi di aggiornamento concorrente I lock vengono rilasciati alla fine della transazione Attenzione: usare i lock può creare problemi di deadlock, se più thread in contemporanea acquisiscono parte delle risorse e non le rilasciano (vedi Problema dei 5 filosofi) 55

Caricamento: Lock modes Lock mode disponibili: NONE: default; legge dal database solo se l'oggetto richiesto non è in cache READ: legge semre l'oggetto dal database UPGRADE: se supportato dal database/dialect, imposta un lock di aggiornamento; se non è possibile ottenerlo, attende che vengano rilasciati i lock che ostacolano UPGRADE_NOWAIT: come UPGRADE, ma se non è possibile ottenere il lock lancia subito una eccezione 56

Aggiornamento dal DB Se vogliamo ottenere l'ultima versione dell'oggetto dal database (eliminando le modifiche fatte da noi) basta utilizzare il metodo refresh() In realtà Hibernate nella maggior parte dei casi lo fa in automatico, non c'è bisogno di chiamare refresh() direttamente Il caso particolare si ha quando l'oggetto viene aggiornato da applicazioni esterne oppure da query SQL: in questo caso Hibernate non può sapere che l'oggetto è stato aggiornato 57

Update Se un oggetto è persistente, ogni modifica che operiamo su di esso viene accodata ed eseguita da Hibernate alla fine della sessione Non è necessario eseguire esplicitamente una operazione di update (con il metodo update()) Nel caso volessimo salvare tutte le operazioni effettuate sul db prima del termine della sessione, possiamo usare il metodo flush() 58

Update: flush() modes La strategia di flushing automatica prevede di salvare ogni oggetto prima di eseguire una query che restituisce l'oggetto stesso Esistono altre strategie, impostabili con setflushmode(): ALWAYS: prima di ogni query effettua flush(), salvando tutti gli oggetti. Lento COMMIT: esegue flush() solo in fase di commit MANUAL: non esegue mai flush(), dobbiamo richiamarlo esplicitamente nel codice 59

Delete Se si deve cancellare un oggetto persistente si può usare il metodo delete() Il parametro di delete() è un Object, che può essere: L'oggetto da cancellare Un oggetto dello stesso tipo di quello da cancellare, con la proprietà chiave impostata (questo si usa se non abbiamo l'oggetto completo ma conosciamo solo l'id) 60

SaveOrUpdate() Il metodo save() rende persistente un oggetto (INSERT) mentre update() lo aggiorna (UPDATE) La prima volta va usato save(), le successive update() Se la prima volta si usa update(), o nelle successive save(), ci sarà un errore Se non sappiamo se usare save() o update(), possiamo usare saveorupdate() che effettua una select per vedere se l'oggetto esiste, e poi chiama save() o update() 61

Disassociazione Può capitare di aver bisogno che un certo oggetto non sia più persistente Dato che ogni modifica dentro una sessione viene tracciata da Hibernate, per poi eseguire gli aggiornamenti, vorremmo evitare che venissero tracciate operazioni che non vanno riportate sul database In questo caso si usa il metodo evict(), che disassocia un oggetto dalla sessione corrente 62

Hibernate Query Language 63

Sintassi base Hibernate fornise un proprio linguaggio di query, basato suglio oggetti e modellato in modo molto simile a SQL Poiché dall'interno di Hibernate si possono sfruttare le informazioni di mapping, molte delle query in HQL sono più compatte delle corrispondenti versioni SQL Ovviamente, HQL viene tradotto in SQL prima di essere inviato al database 64

Sintassi base SELECT È identico all'equivalente SQL, solo che la parte di proiezione (SELECT nome, cognome) è opzionale: se non si specifica si assume SELECT * La clausola FROM è seguita dal nome di una classe, piuttosto che di una tabella 65

CreateQuery Un oggetto di tipo Query può essere ottenuto, a partire dalla corrispondente stringa HQL, tramite il metodo createquery() di Session Query q = session.createquery( from User ); 66

Controllare codice SQL generato Il codice HQL viene convertito in SQL prima di essere inviato al database Può capitare che, in alcuni casi, la traduzione sia una query SQL inefficiente Possiamo visualizzare le traduzioni tramite: Hibernate console in Eclipse File di Log, se abilitiamo la proprietà show_sql nel file di configurazione di Hibernate 67

Filtri condizionali Ovvero la clausola WHERE Possiamo usare tutti gli operatori tipici di SQL (OR, AND, =, <>, like eccetera) In più possiamo definire dei parametri, per realizzare query parametriche I parametri si inseriscono come :nomeparametro Es: From User where name=:name 68

Named Parameters I Named Parameters ci aiutano a difendere la nostra applicazione dagli attacchi di SQL Injection Infatti la sostituzione tra parametri e valore effettivo avviene controllando il tipo esatto dell'oggetto passato Es. Query query = session.createquery( from User where address=:address ); query.setentity( address, myaddress); 69

Pagination Normalmente in una web application restituiremo solo un certo numero di dati all'utente Se sono molti, questo significa mostrare una pagina alla volta L'oggetto query possiede due metodi per supportare questa funzionalità: setfirstresult(int) : indica la tupla di partenza setmaxresults(int) : indica quante tuple prelevare 70

Risultato unico L'oggetto Query ha un metodo list() che restituisce tutti i risultati di una query Possiede anche un metodo uniqueresult() che restituisce solo un oggetto Se l'oggetto è più di uno, lancia una eccezione Quando vogliamo ottenere solo il primo risultato, dovremo usare una combinazione di uniqueresult() e setmaxresults(1)

Order by HQL supporta la clausola Order By che viene usata come in SQL order by nomeproprietà [desc asc] Se vogliamo ordinare per più proprietà, basta separarle con la virgola

Join Tramite le join si possono usare più classi in una sola query Hibernate supporta più tipi di join: Inner, cross, left outer, right outer, full outer Se ci sono i mapping non c'è bisogno di specificare le condizioni di join

Aggregazioni HQL supporta gli operatori di aggregazione: avg(name) count(name *) max(name) min(name) sum(name)

Aggiornamenti in blocco Quando serve aggiornare o cancellare un certo numero di oggetti contemporaneamente, usare un ciclo for potrebbe essere inefficiente Si possono usare gli equivalenti HQL di UPDATE e DELETE Basta creare una query di update/delete, e poi chiamarne il metodo executeupdate()

SQL Nativo L'uso di SQL nativo si dovrebbe evitare per ottenere la massima portabilità; se proprio è necessario, possiamo creare una query in SQL utilizzando il metodo Session.createSQLQuery(String)