Оскільки це дуже поширене питання, я написав
цю статтю , на якій ґрунтується ця відповідь.
Методи 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.