Impaginazione ibernata

1. Panoramica

Questo articolo è una rapida introduzione all'impaginazione in Hibernate . Esamineremo l'HQL standard e l' API ScrollableResults e, infine, l'impaginazione con Hibernate Criteria.

2. Impaginazione con HQL e setFirstResult, setMaxResults API

Il modo più semplice e comune per eseguire l'impaginazione in Hibernate è usare HQL :

Session session = sessionFactory.openSession(); Query query = sess.createQuery("From Foo"); query.setFirstResult(0); query.setMaxResults(10); List fooList = fooList = query.list();

Questo esempio utilizza un'entità Foo di base ed è molto simile a JPA con implementazione JQL: l'unica differenza è il linguaggio di query.

Se attiviamo la registrazione per Hibernate , vedremo in esecuzione il seguente SQL:

Hibernate: select foo0_.id as id1_1_, foo0_.name as name2_1_ from Foo foo0_ limit ?

2.1. Il conteggio totale e l'ultima pagina

Una soluzione di impaginazione non è completa senza conoscere il numero totale di entità :

String countQ = "Select count (f.id) from Foo f"; Query countQuery = session.createQuery(countQ); Long countResults = (Long) countQuery.uniqueResult();

Infine, dal numero totale e da una data dimensione della pagina, possiamo calcolare l'ultima pagina :

int pageSize = 10; int lastPageNumber = (int) (Math.ceil(countResults / pageSize));

A questo punto possiamo guardare un esempio completo per l'impaginazione , dove stiamo calcolando l'ultima pagina e poi recuperandola:

@Test public void givenEntitiesExist_whenRetrievingLastPage_thenCorrectSize() { int pageSize = 10; String countQ = "Select count (f.id) from Foo f"; Query countQuery = session.createQuery(countQ); Long countResults = (Long) countQuery.uniqueResult(); int lastPageNumber = (int) (Math.ceil(countResults / pageSize)); Query selectQuery = session.createQuery("From Foo"); selectQuery.setFirstResult((lastPageNumber - 1) * pageSize); selectQuery.setMaxResults(pageSize); List lastPage = selectQuery.list(); assertThat(lastPage, hasSize(lessThan(pageSize + 1))); }

3. Impaginazione con Hibernate utilizzando HQL e l'API ScrollableResults

L'uso di ScrollableResul ts per implementare l'impaginazione ha il potenziale per ridurre le chiamate al database . Questo approccio trasmette il set di risultati mentre il programma lo scorre, eliminando quindi la necessità di ripetere la query per riempire ogni pagina:

String hql = "FROM Foo f order by f.name"; Query query = session.createQuery(hql); int pageSize = 10; ScrollableResults resultScroll = query.scroll(ScrollMode.FORWARD_ONLY); resultScroll.first(); resultScroll.scroll(0); List fooPage = Lists.newArrayList(); int i = 0; while (pageSize > i++) { fooPage.add((Foo) resultScroll.get(0)); if (!resultScroll.next()) break; }

Questo metodo non è solo efficiente in termini di tempo (solo una chiamata al database), ma consente all'utente di accedere al conteggio totale del set di risultati senza una query aggiuntiva :

resultScroll.last(); int totalResults = resultScroll.getRowNumber() + 1;

D'altra parte, tieni presente che, sebbene lo scorrimento sia abbastanza efficiente, una finestra grande può occupare una discreta quantità di memoria .

4. Impaginazione con Hibernate utilizzando l'API Criteria

Infine, diamo un'occhiata a una soluzione più flessibile, utilizzando criteri:

Criteria criteria = session.createCriteria(Foo.class); criteria.setFirstResult(0); criteria.setMaxResults(pageSize); List firstPage = criteria.list();

L'API di query Hibernate Criteria rende molto semplice ottenere anche il conteggio totale , utilizzando un oggetto Projection :

Criteria criteriaCount = session.createCriteria(Foo.class); criteriaCount.setProjection(Projections.rowCount()); Long count = (Long) criteriaCount.uniqueResult();

Come puoi vedere, l'utilizzo di questa API comporterà un codice minimamente più dettagliato rispetto al semplice HQL, ma l'API è completamente indipendente dai tipi e molto più flessibile .

5. conclusione

Questo articolo è una rapida introduzione ai vari modi di eseguire l'impaginazione in Hibernate.

L'implementazione di questo tutorial Spring JPA può essere trovata nel progetto GitHub: questo è un progetto basato su Eclipse, quindi dovrebbe essere facile da importare ed eseguire così com'è.