分页
createPaginator 提供了基于页码和基于游标两种分页方式。
基于页码的分页
Section titled “基于页码的分页”import { createPaginator } from "@ventostack/database";
const paginator = createPaginator(db);
router.get("/users", async (ctx) => { const page = Number(ctx.query.page ?? 1); const limit = Number(ctx.query.limit ?? 20);
const result = await paginator.paginate( db.query(UserModel).where("active", "=", true).orderBy("createdAt", "DESC"), { page, limit } );
return ctx.json({ data: result.data, pagination: { page: result.page, limit: result.limit, total: result.total, totalPages: result.totalPages, hasNextPage: result.hasNextPage, hasPrevPage: result.hasPrevPage, } });});响应示例:
{ "data": [...], "pagination": { "page": 2, "limit": 20, "total": 150, "totalPages": 8, "hasNextPage": true, "hasPrevPage": true }}基于游标的分页(无限滚动)
Section titled “基于游标的分页(无限滚动)”游标分页性能更优,适合大数据集和无限滚动场景:
router.get("/feed", async (ctx) => { const cursor = ctx.query.cursor; const limit = Number(ctx.query.limit ?? 20);
const result = await paginator.cursorPaginate( db.query(PostModel).where("published", "=", true).orderBy("createdAt", "DESC"), { cursor, limit, cursorField: "createdAt" } );
return ctx.json({ data: result.data, nextCursor: result.nextCursor, hasMore: result.hasMore, });});响应示例:
{ "data": [...], "nextCursor": "2024-01-15T10:30:00.000Z", "hasMore": true}客户端下次请求时传入 ?cursor=2024-01-15T10:30:00.000Z。
Paginator 接口
Section titled “Paginator 接口”interface PaginateOptions { page: number; limit: number;}
interface PaginateResult<T> { data: T[]; page: number; limit: number; total: number; totalPages: number; hasNextPage: boolean; hasPrevPage: boolean;}
interface CursorPaginateOptions { cursor?: string; limit: number; cursorField: string;}
interface CursorPaginateResult<T> { data: T[]; nextCursor?: string; hasMore: boolean;}