千万不要使用offset,因为offset还要读取offset之前的所有数据,效率非常低。
您需要按索引的唯一属性进行排序,并在 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 地图分页地点查询如何与该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 或 Jackson 可以在这方面为您节省几行代码。