1. Überblick

JPA-Paginierung

1. Überblick

Dieser Artikel zeigt, wiepagination in the Java Persistence API implementiert werden.

Es wird erklärt, wie Paging mit einfachem JQL und den typsichereren kriterienbasierten APIs durchgeführt wird, und die Vorteile und bekannten Probleme jeder Implementierung werden erläutert.

Weitere Lektüre:

Paginierung mit Federauflage und AngularJS-Tisch

Ein ausführlicher Einblick in die Implementierung einer einfachen API mit Paginierung in Spring und deren Verwendung in AngularJS und UI Grid.

Read more

Spring JPA - Mehrere Datenbanken

So richten Sie Spring Data JPA für die Arbeit mit mehreren separaten Datenbanken ein.

Read more

Frühlingsdaten JPA @Query

Erfahren Sie, wie Sie die Annotation @Query in Spring Data JPA verwenden, um benutzerdefinierte Abfragen mit JPQL und nativem SQL zu definieren.

Read more

2. Paginierung mit JQL und der APIsetFirstResult(),setMaxResults()

Die einfachste Möglichkeit, die Paginierung zu implementieren, besteht darin,the Java Query Language zu verwenden. Erstellen Sie eine Abfrage und konfigurieren Sie sie übersetMaxResults ** undsetFirstResult:

Query query = entityManager.createQuery("From Foo");
int pageNumber = 1;
int pageSize = 10;
query.setFirstResult((pageNumber-1) * pageSize);
query.setMaxResults(pageSize);
List  fooList = query.getResultList();

Die API ist einfach:

  • *setFirstResult(int*): Legt die Versatzposition in der Ergebnismenge fest, um die Paginierung zu starten

  • setMaxResults(int): Legt die maximale Anzahl von Entitäten fest, die auf der Seite enthalten sein sollen

2.1. Die Gesamtzahl und die letzte Seite

Für eine vollständigere Paginierungslösung benötigen wir außerdemthe total result count:

Query queryTotal = entityManager.createQuery
    ("Select count(f.id) from Foo f");
long countResult = (long)queryTotal.getSingleResult();

Die Berechnung vonthe last page ist ebenfalls sehr nützlich:

int pageSize = 10;
int pageNumber = (int) ((countResult / pageSize) + 1);

Beachten Sie, dass für diesen Ansatz zum Abrufen der Gesamtanzahl der Ergebnismenge eine zusätzliche Abfrage (für die Anzahl) erforderlich ist.

3. Paginierung mit JQL unter Verwendung der IDs von Entitäten

Eine einfache alternative Paginierungsstrategie istfirst retrieve the full ids und dann - basierend auf diesen -retrieve the full entities. Dies ermöglicht eine bessere Kontrolle über das Abrufen von Entitäten, bedeutet aber auch, dass die gesamte Tabelle geladen werden muss, um die IDs abzurufen:

Query queryForIds = entityManager.createQuery(
  "Select f.id from Foo f order by f.lastName");
List fooIds = queryForIds.getResultList();
Query query = entityManager.createQuery(
  "Select f from Foo e where f.id in :ids");
query.setParameter("ids", fooIds.subList(0,10));
List fooList = query.getResultList();

Beachten Sie außerdem, dass zwei verschiedene Abfragen erforderlich sind, um die vollständigen Ergebnisse abzurufen.

4. Paginierung mit JPA unter Verwendung der Kriterien-API

Schauen wir uns als nächstes an, wie wirleverage the JPA Criteria API implementieren können:

int pageSize = 10;
CriteriaBuilder criteriaBuilder = entityManager
  .getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder
  .createQuery(Foo.class);
Root from = criteriaQuery.from(Foo.class);
CriteriaQuery select = criteriaQuery.select(from);
TypedQuery typedQuery = entityManager.createQuery(select);
typedQuery.setFirstResult(0);
typedQuery.setMaxResults(pageSize);
List fooList = typedQuery.getResultList();

Dies ist hilfreich, wenn dynamische, ausfallsichere Abfragen erstellt werden sollen. Im Gegensatz zu "fest codierten", "stringbasierten" JQL- oder HQL-Abfragen reduziertJPA Criteria Laufzeitfehler, da der Compiler dynamisch nach Abfragefehlern sucht.

Mit JPA-Kriteriengetting the total number of entitiesist es einfach genug:

CriteriaQuery countQuery = criteriaBuilder
  .createQuery(Long.class);
countQuery.select(criteriaBuilder.count(
  countQuery.from(Foo.class)));
Long count = entityManager.createQuery(countQuery)
  .getSingleResult();

Das Endergebnis ista full pagination solution unter Verwendung der JPA-Kriterien-API:

int pageNumber = 1;
int pageSize = 10;
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery countQuery = criteriaBuilder
  .createQuery(Long.class);
countQuery.select(criteriaBuilder
  .count(countQuery.from(Foo.class)));
Long count = entityManager.createQuery(countQuery)
  .getSingleResult();

CriteriaQuery criteriaQuery = criteriaBuilder
  .createQuery(Foo.class);
Root from = criteriaQuery.from(Foo.class);
CriteriaQuery select = criteriaQuery.select(from);

TypedQuery typedQuery = entityManager.createQuery(select);
while (pageNumber < count.intValue()) {
    typedQuery.setFirstResult(pageNumber - 1);
    typedQuery.setMaxResults(pageSize);
    System.out.println("Current page: " + typedQuery.getResultList());
    pageNumber += pageSize;
}

5. Fazit

In diesem Artikel wurden die grundlegenden Paginierungsoptionen von JPA erläutert.

Einige weisen Nachteile auf - hauptsächlich in Bezug auf die Abfrageleistung. Diese werden jedoch in der Regel durch eine verbesserte Steuerung und allgemeine Flexibilität ausgeglichen.

Die Implementierung dieses Spring JPA-Lernprogramms finden Sie inthe GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.