Mappatura di una query di ibernazione a una classe personalizzata

1. Panoramica

Quando usiamo Hibernate per recuperare i dati dal database, per impostazione predefinita, utilizza i dati recuperati per costruire l'intero oggetto grafico per l'oggetto richiesto. Ma a volte potremmo voler recuperare solo una parte dei dati, preferibilmente in una struttura piatta.

In questo breve tutorial, vedremo come possiamo ottenere questo risultato in Hibernate usando una classe personalizzata.

2. Le entità

Per prima cosa, diamo un'occhiata alle entità che useremo per recuperare i dati:

@Entity public class DeptEmployee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String employeeNumber; private String designation; private String name; @ManyToOne private Department department; // constructor, getters and setters } @Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String name; @OneToMany(mappedBy="department") private List employees; public Department(String name) { this.name = name; } // getters and setters  }

Qui abbiamo due entità: DeptEmployee e Department . Per semplicità, supponiamo che un DeptEmployee possa appartenere a un solo dipartimento.

Tuttavia, un dipartimento può avere più dipendenti .

3. Una classe di risultati query personalizzata

Supponiamo di voler stampare un elenco di tutti i dipendenti con solo il loro nome e il nome del loro dipartimento.

In genere, recupereremmo questi dati con una query come questa:

Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee"); List deptEmployees = query.list();

Questo recupererà tutti i dipendenti, tutte le loro proprietà, il dipartimento associato e tutte le sue proprietà.

Ma, in questo caso particolare, questo potrebbe essere un po 'costoso in quanto abbiamo solo bisogno del nome del dipendente e del nome del dipartimento.

Un modo per recuperare solo le informazioni di cui abbiamo bisogno è specificare le proprietà nella clausola select.

Ma, quando lo facciamo, Hibernate restituisce un elenco di array invece di un elenco di oggetti:

Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m"); List managers = query.list(); Object[] manager = (Object[]) managers.get(0); assertEquals("John Smith", manager[0]); assertEquals("Sales", manager[1]);

Come possiamo vedere, i dati restituiti sono un po 'macchinosi da elaborare. Ma, fortunatamente, possiamo convincere Hibernate a popolare questi dati in una classe.

Diamo un'occhiata alla classe Result che useremo per popolare i dati recuperati in:

public class Result { private String employeeName; private String departmentName; public Result(String employeeName, String departmentName) { this.employeeName = employeeName; this.departmentName = departmentName; } public Result() { } // getters and setters }

Nota che la classe non è un'entità ma solo un POJO. Tuttavia, possiamo anche usare un'entità purché abbia un costruttore che accetta tutti gli attributi che vogliamo popolare come parametri.

Vedremo perché il costruttore è importante nella prossima sezione.

4. Utilizzo di un costruttore in HQL

Ora, diamo un'occhiata all'HQL che utilizza questa classe:

Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name)" + " from com.baeldung.hibernate.entities.DeptEmployee m"); List results = query.list(); Result result = results.get(0); assertEquals("John Smith", result.getEmployeeName()); assertEquals("Sales", result.getDepartmentName());

Qui, usiamo il costruttore che abbiamo definito nella classe Result insieme alle proprietà che vogliamo recuperare. Ciò restituirà un elenco di oggetti Risultato con i dati popolati dalle colonne.

Come possiamo vedere, l'elenco restituito è più facile da elaborare rispetto all'utilizzo di un elenco di array di oggetti.

È importante notare che dobbiamo utilizzare il nome completo della classe nella query.

5. Utilizzo di un ResultTransformer

Un'alternativa all'uso di un costruttore nella query HQL è usare un ResultTransformer:

Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName" + " from com.baeldung.hibernate.entities.DeptEmployee m"); query.setResultTransformer(Transformers.aliasToBean(Result.class)); List results = query.list(); Result result = results.get(0); assertEquals("John Smith", result.getEmployeeName()); assertEquals("Sales", result.getDepartmentName());

Usiamo i Transformers. aliasToBean () per utilizzare i dati recuperati per popolare gli oggetti Result .

Di conseguenza, dobbiamo assicurarci che i nomi delle colonne o i loro alias nell'istruzione select corrispondano alle proprietà della classe Result .

Si noti che Query.setResultTransformer ( ResultTransformer ) è stato deprecato da Hibernate 5.2.

6. Conclusione

In questo articolo abbiamo visto come utilizzare una classe personalizzata per recuperare i dati in una forma di facile lettura.

Il codice sorgente che accompagna questo articolo è disponibile su GitHub.