Da dies eine sehr häufige Frage ist, habe ich
diesen Artikel geschrieben , auf dem diese Antwort basiert.
Die setFirstResultund setMaxResults QueryMethoden
Für eine JPA und Ruhezustand Query, das setFirstResultist das Äquivalent von Verfahren OFFSETund das setMaxResultsVerfahren ist das Äquivalent von LIMIT:
List<Post> posts = entityManager
.createQuery(
"select p " +
"from Post p " +
"order by p.createdOn ")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
Die LimitHandlerAbstraktion
Der Ruhezustand LimitHandlerdefiniert die datenbankspezifische Paginierungslogik. Wie das folgende Diagramm zeigt, unterstützt der Ruhezustand viele datenbankspezifische Paginierungsoptionen:

Abhängig vom zugrunde liegenden relationalen Datenbanksystem, das Sie verwenden, verwendet die obige JPQL-Abfrage nun die richtige Paginierungssyntax.
MySQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?, ?
PostgreSQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
SQL Server
SELECT p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
OFFSET ? ROWS
FETCH NEXT ? ROWS ONLY
Orakel
SELECT *
FROM (
SELECT
row_.*, rownum rownum_
FROM (
SELECT
p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
) row_
WHERE rownum <= ?
)
WHERE rownum_ > ?
Der Vorteil von setFirstResultund setMaxResultsbesteht darin, dass Hibernate die datenbankspezifische Paginierungssyntax für alle unterstützten relationalen Datenbanken generieren kann.
Sie sind nicht nur auf JPQL-Abfragen beschränkt. Sie können die setFirstResultund setMaxResults-Methode sieben für native SQL-Abfragen verwenden.
Native SQL-Abfragen
Sie müssen die datenbankspezifische Paginierung nicht fest codieren, wenn Sie native SQL-Abfragen verwenden. Der Ruhezustand kann dies zu Ihren Abfragen hinzufügen.
Wenn Sie diese SQL-Abfrage unter PostgreSQL ausführen:
List<Tuple> posts = entityManager
.createNativeQuery(
"SELECT " +
" p.id AS id, " +
" p.title AS title " +
"from post p " +
"ORDER BY p.created_on", Tuple.class)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
Der Ruhezustand wird es wie folgt transformieren:
SELECT p.id AS id,
p.title AS title
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
Cool, oder?
Jenseits der SQL-basierten Paginierung
Die Paginierung ist gut, wenn Sie die Filter- und Sortierkriterien indizieren können. Wenn Ihre Paginierungsanforderungen eine dynamische Filterung implizieren, ist es viel besser, eine Lösung mit invertiertem Index wie ElasticSearch zu verwenden.
Weitere Informationen finden Sie in diesem Artikel .
Hibernate-5.0.12. Ist das noch nicht verfügbar? Es wäre sehr schwer,setMaxResultsungefähr eine Million Datensätze zu erhalten und dann den Filter darauf anzuwenden , wie @Rachel in der Antwort von @skaffman bemerkt hat.