Winterschlaf-Paginierung
1. Überblick
Dieser Artikel ist eine schnelleintroduction to Pagination in Hibernate. Wir werden uns sowohl die Standard-HQL als auch dieScrollableResults-API und schließlich die Paginierung mit Hibernate-Kriterien ansehen.
Weitere Lektüre:
Bootstrapping Hibernate 5 mit Spring
Eine schnelle und praktische Anleitung zur Integration von Hibernate 5 in Spring.
Hibernate Inheritance Mapping
Ein praktischer Leitfaden zum Verständnis verschiedener Vererbungszuordnungsstrategien mit JPA / Hibernate.
Ruhezustand / JPA-SQL-Anweisungen von Spring Boot anzeigen
Erfahren Sie, wie Sie die Protokollierung der generierten SQL-Anweisungen in Ihrer Spring Boot-Anwendung konfigurieren können.
2. Paginierung mit HQL undsetFirstResult,setMaxResults API
Die einfachste und häufigste Methode zur Paginierung im Ruhezustand istusing HQL:
Session session = sessionFactory.openSession();
Query query = sess.createQuery("From Foo");
query.setFirstResult(0);
query.setMaxResults(10);
List fooList = fooList = query.list();
In diesem Beispiel wird eine grundlegendeFoo-Entität verwendet, die der JPA mit JQL-Implementierung sehr ähnlich ist. Der einzige Unterschied besteht in der Abfragesprache.
Wenn wirlogging for Hibernate 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, ohnethe total number of entities 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ößethe last page berechnen:
int pageSize = 10;
int lastPageNumber = (int) (Math.ceil(countResults / pageSize));
An dieser Stelle können wir unsa complete example for pagination ansehen, wo 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 mit Ruhezustand Verwenden von HQL und der ScrollableResults-API
Die Verwendung vonScrollableResulM. zur Implementierung der Paginierung kann zureduce database calls führen. 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 dietotal count of the result set without an additional query:
resultScroll.last();
int totalResults = resultScroll.getRowNumber() + 1;
Beachten Sie andererseits, dass ein großes Fenster, obwohl das Scrollen sehr effizient ist, eine anständige Menge vonmemory beanspruchen kann.
4. Paginierung mit Ruhezustand mithilfe der Kriterien-API
Schauen wir uns zum Schlussa more flexible solution 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, auchget the total count zu verwenden - indem einProjection-Objekt verwendet wird:
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 bei einfachem HQL, jedoch zuthe API is fully type safe and a lot more flexible.
5. Fazit
Dieser Artikel ist eine kurze Einführung in die verschiedenen Möglichkeiten der Paginierung in Hibernate.
Die Implementierung dieses Spring JPA-Lernprogramms finden Sie inthe GitHub project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.