Paginierung im Ruhezustand

1. Übersicht

Dieser Artikel ist eine kurze Einführung in die Paginierung im Ruhezustand . Wir werden uns sowohl die Standard-HQL- als auch die ScrollableResults- API und schließlich die Paginierung mit Hibernate-Kriterien ansehen .

2. Paginierung Mit HQL und setFirstResult die setMaxResults- API

Die einfachste und häufigste Methode zur Paginierung im Ruhezustand ist die Verwendung von HQL :

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

Dieses Beispiel verwendet eine grundlegende Foo- Entität und ist der JPA mit JQL-Implementierung sehr ähnlich - der einzige Unterschied ist die Abfragesprache.

Wenn wir die Protokollierung für den Ruhezustand aktivieren , wird die folgende SQL ausgeführt:

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

2.1. Die Gesamtzahl und die letzte Seite

Eine Paginierungslösung ist nicht vollständig, ohne die Gesamtzahl der Entitäten zu kennen :

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

Und schließlich können wir aus der Gesamtzahl und einer bestimmten Seitengröße die letzte Seite berechnen :

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

An dieser Stelle können wir uns ein vollständiges Beispiel für die Paginierung ansehen, bei dem wir die letzte Seite berechnen und dann abrufen:

@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. Paginierung im Ruhezustand Verwenden von HQL und der ScrollableResults-API

Durch die Verwendung von ScrollableResul ts zur Implementierung der Paginierung können Datenbankaufrufe reduziert werden . Bei diesem Ansatz wird die Ergebnismenge beim Scrollen durch das Programm gestreamt, sodass die Abfrage nicht mehr wiederholt werden muss, um jede Seite zu füllen:

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; }

Diese Methode ist nicht nur zeiteffizient (nur ein Datenbankaufruf), sondern ermöglicht dem Benutzer auch den Zugriff auf die Gesamtzahl der Ergebnismenge ohne zusätzliche Abfrage :

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

Beachten Sie andererseits, dass ein großes Fenster zwar recht effizient scrollen kann, jedoch möglicherweise ausreichend Speicherplatz beansprucht .

4. Paginierung im Ruhezustand mithilfe der Kriterien-API

Schauen wir uns zum Schluss eine flexiblere Lösung an - anhand von Kriterien:

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

Die Abfrage-API für Kriterien für den Ruhezustand macht es sehr einfach, auch die Gesamtzahl zu ermitteln - mithilfe eines Projektionsobjekts :

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

Wie Sie sehen können, führt die Verwendung dieser API zu einem minimal ausführlicheren Code als einfaches HQL, aber die API ist vollständig typsicher und viel flexibler .

5. Schlussfolgerung

Dieser Artikel ist eine kurze Einführung in die verschiedenen Möglichkeiten der Paginierung im Ruhezustand.

Die Implementierung dieses Spring JPA-Tutorials finden Sie im GitHub-Projekt - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.