Никогда не используйте смещение, потому что смещение также считывает все данные до смещения, что очень неэффективно.
Вам необходимо упорядочить по индексируемому уникальному свойству, вернуть значение последнего свойства элемента в вызове API и использовать предложение WHERE
, чтобы начать с того места, где вы оставили. Значение свойства этого последнего элемента будет вашей позицией курсора. Например, простой разбитый на страницы запрос, использующий первичный ключ id
в качестве курсора, будет выглядеть так:
List<MyEntity> entities = entityManager
.createQuery("""
FROM
MyEntity e
WHERE
e.id > :cursorPosition
ORDER BY
e.id ASC
""", MyEntity.class)
.setParameter("cursorPosition", cursorPosition)
.setMaxResults(pageSize)
.getResultList()
При первом вызове API значение cursorPosition
может быть равно 0. Второй - вы получите от клиента курсор, который клиент получил от первого вызова. Посмотрите, как запрос Google Maps разбивает на страницы , работает с атрибутом nextPageToken
.
Ваш курсор должен быть строкой, которая идентифицирует все параметры вашего запроса. Поэтому, если у вас есть дополнительные параметры, они должны быть получены с помощью курсора.
Я считаю, что вы можете сделать это несколькими способами. Один из способов - объединить все параметры и cursorPosition
в строку, закодировать ее в строку, удобную для URL-адреса, например Base64, и при получении обратно декодировать ее и разделить строку на исходные параметры:
String nextPageToken = Base64.getUrlEncoder()
.encodeToString("indexProperty=id&cursorPos=123&ageBiggerThan=65".getBytes())
Ваш вызов API вернет JSON, как это:
{
"items": [ ... ],
"nextPageToken": "aW5kZXhQcm9wZXJ0eT1pZCZjdXJzb3JQb3M9MTIzJmFnZUJpZ2dlclRoYW49NjU="
}
И клиент следующий звонок:
GET https://www.example.com/api/myservice/v1/myentity?pageToken=aW5kZXhQcm9wZXJ0eT1pZCZjdXJzb3JQb3M9MTIzJmFnZUJpZ2dlclRoYW49NjU=
Часть объединения и разбиения строки курсора может быть утомительной, я действительно не знаю, есть ли библиотека, которая обрабатывает эту работу по созданию токенов и их синтаксическому анализу, я на самом деле в этом вопросе, потому что я искал Это. Но я думаю, что GSON или Джексон могут сэкономить вам строки кода на этом.