分页查询操作

import { sql, SQL } from "drizzle-orm";

  // 分页查询参数接口
  interface PaginationParams {
    page?: number;
    pageSize?: number;
  }

  // 分页查询结果接口
  interface PaginationResult<T> {
    data: T[];
    total: number;
    page: number;
    pageSize: number;
    totalPages: number;
  }

  // 通用分页查询函数
  export async function paginatedQuery<T>(
    params: PaginationParams & {
      query: any; // Drizzle query builder
      whereClause?: SQL;
      orderBy?: SQL | SQL[];
    }
  ): Promise<PaginationResult<T>> {
    const { page = 1, pageSize = 10, query, whereClause, orderBy } = params;

    // 计算偏移量
    const offset = (page - 1) * pageSize;

    // 构建基础查询
    let baseQuery = query;
    if (whereClause) {
      baseQuery = baseQuery.where(whereClause);
    }

    // 执行并发查询
    const [data, countResult] = await Promise.all([
      // 查询数据
      (() => {
        let dataQuery = baseQuery;
        if (orderBy) {
          dataQuery = Array.isArray(orderBy)
            ? dataQuery.orderBy(...orderBy)
            : dataQuery.orderBy(orderBy);
        }
        return dataQuery.limit(pageSize).offset(offset);
      })(),

      // 查询总数
      db()
        .select({ count: sql<number>`count(*)` })
        .from(baseQuery.as('subquery'))
    ]);

    const total = Number(countResult[0]?.count) || 0;
    const totalPages = Math.ceil(total / pageSize);

    return {
      data,
      total,
      page,
      pageSize,
      totalPages
    };
  }

使用示例

// 使用示例:    
// const result = await paginatedQuery({                                                                                           
//   page: 1,                                                                                                                      
//   pageSize: 10,                                                                                                                 
//   query: db().select().from(packageAddresses),                                                                                  
//   whereClause: and(                                                                                                             
//     eq(packageAddresses.user_uuid, userUuid),                                                                                   
//     eq(packageAddresses.address_purpose, "sender")                                                                              
//   ),                                                                                                                            
//   orderBy: desc(packageAddresses.created_at)                                                                                    
// });                                                                                                                    

这个封装提供了:

1. 统一的分页参数和返回格式

2. 自动计算总页数

3. 并发执行数据查询和计数查询

4. 支持自定义查询条件和排序

5. 自动转换count结果为数字类型