Оскільки це дуже поширене питання, я написав
цю статтю , на якій ґрунтується ця відповідь.
Методи setFirstResultі setMaxResults Queryметоди
Для JPA і Hibernate Query, то setFirstResultметод є еквівалентом OFFSET, а setMaxResultsметод є еквівалентом LIMIT:
List<Post> posts = entityManager
.createQuery(
"select p " +
"from Post p " +
"order by p.createdOn ")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
LimitHandlerабстракція
Hibernate LimitHandlerвизначає логіку розбиття на певну базу даних, і, як показано на наступній схемі, Hibernate підтримує безліч параметрів сторінки для конкретних баз даних:

Тепер, залежно від основної системи реляційних баз даних, яку ви використовуєте, вищезазначений запит JPQL використовуватиме належний синтаксис сторінки розбиття.
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
Oracle
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_ > ?
Перевага використання setFirstResultі в setMaxResultsтому , що Hibernate може генерувати бази даних конкретних посторінковий синтаксису для будь-яких підтримуваних реляційних баз даних.
І ви не обмежені лише запитами JPQL. Ви можете використовувати setFirstResultі setMaxResultsметод сім для нативних запитів SQL.
Рідні запити SQL
Вам не доведеться жорстко кодувати базові сторінки для використання під час використання нативних SQL-запитів. Hibernate може додати це до ваших запитів.
Отже, якщо ви виконуєте цей SQL-запит на PostgreSQL:
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();
Зимова сплячка перетворить її наступним чином:
SELECT p.id AS id,
p.title AS title
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
Класно, правда?
Поза базування на основі SQL
Пагинація добре, коли ви можете проіндексувати критерії фільтрування та сортування. Якщо ваші вимоги до сторінок передбачають динамічну фільтрацію, це набагато кращий підхід використовувати рішення з інвертованим індексом, наприклад ElasticSearch.
Перегляньте цю статтю для отримання більш детальної інформації.
Hibernate-5.0.12. Це все ще недоступно? Було б дуже важко отримати мільйон або близько того записів, а потім застосувати до нього фільтр,setMaxResultsяк помітив @Rachel у відповіді @skaffman.