You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用TypeScript实现MySQL Aurora数据库查询分页?

实现MySQL Aurora分页的两种方案(TypeScript + Node18 + MySQL2)

一、偏移量分页(LIMIT/OFFSET)

这是最直观的分页方式,适合数据量不大的场景,通过页码和每页条数计算偏移量来获取数据。

实现步骤

  • 从API请求的查询参数中获取page(当前页码,默认1)和pageSize(每页条数,默认10)
  • 计算偏移量:offset = (page - 1) * pageSize
  • 执行两条SQL:一条查询当前页数据,一条查询总记录数,用于返回分页元数据

代码示例

import { APIGatewayProxyHandlerV2 } from 'aws-lambda';
import mysql from 'mysql2/promise';

// 数据库连接配置(建议用环境变量存储敏感信息)
const dbConfig = {
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  ssl: { rejectUnauthorized: false } // Aurora需SSL连接
};

export const handler: APIGatewayProxyHandlerV2 = async (event) => {
  // 解析并校验分页参数
  const page = parseInt(event.queryStringParameters?.page || '1', 10);
  const pageSize = parseInt(event.queryStringParameters?.pageSize || '10', 10);
  if (page < 1 || pageSize < 1 || pageSize > 100) { // 限制最大每页条数避免性能问题
    return {
      statusCode: 400,
      body: JSON.stringify({ error: '无效的分页参数' })
    };
  }
  const offset = (page - 1) * pageSize;

  let connection;
  try {
    connection = await mysql.createConnection(dbConfig);
    
    // 查询当前页数据(以users表为例,根据你的业务表结构调整)
    const [rows] = await connection.execute(
      'SELECT id, name, email FROM users ORDER BY id ASC LIMIT ? OFFSET ?',
      [pageSize, offset]
    );

    // 查询总记录数,用于计算总页数
    const [countResult] = await connection.execute('SELECT COUNT(*) as total FROM users');
    const total = (countResult as any)[0].total;
    const totalPages = Math.ceil(total / pageSize);

    return {
      statusCode: 200,
      body: JSON.stringify({
        data: rows,
        pagination: {
          currentPage: page,
          pageSize: pageSize,
          totalItems: total,
          totalPages: totalPages
        }
      })
    };
  } catch (error) {
    console.error('数据库查询失败:', error);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: '服务器内部错误' })
    };
  } finally {
    if (connection) {
      await connection.end();
    }
  }
};

二、键集分页(Cursor-Based Pagination)

当数据量很大时,OFFSET会导致数据库扫描大量无关数据,性能下降。键集分页通过上一页最后一条数据的唯一标识(比如id、时间戳)作为游标,避免偏移量的性能问题,适合滚动加载场景。

实现步骤

  • 从API请求的查询参数中获取cursor(上一页最后一条数据的id,首次请求为空)和pageSize
  • SQL中用WHERE id > ?(或根据排序字段调整条件)配合LIMIT获取下一页数据
  • 返回当前页数据和下一页的游标(当前页最后一条数据的id)

代码示例

import { APIGatewayProxyHandlerV2 } from 'aws-lambda';
import mysql from 'mysql2/promise';

const dbConfig = {
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  ssl: { rejectUnauthorized: false }
};

export const handler: APIGatewayProxyHandlerV2 = async (event) => {
  const cursor = event.queryStringParameters?.cursor;
  const pageSize = parseInt(event.queryStringParameters?.pageSize || '10', 10);
  if (pageSize < 1 || pageSize > 100) {
    return {
      statusCode: 400,
      body: JSON.stringify({ error: '无效的分页参数' })
    };
  }

  let connection;
  try {
    connection = await mysql.createConnection(dbConfig);
    
    let query = 'SELECT id, name, email FROM users ORDER BY id ASC LIMIT ?';
    let params: any[] = [pageSize];

    // 存在游标时,添加WHERE条件过滤数据
    if (cursor) {
      query = 'SELECT id, name, email FROM users WHERE id > ? ORDER BY id ASC LIMIT ?';
      params = [parseInt(cursor, 10), pageSize];
    }

    const [rows] = await connection.execute(query, params);
    const data = rows as any[];
    // 生成下一页游标:当前页数据条数等于pageSize时,说明还有后续数据
    const nextCursor = data.length === pageSize ? data[data.length - 1].id : null;

    return {
      statusCode: 200,
      body: JSON.stringify({
        data: data,
        pagination: {
          pageSize: pageSize,
          nextCursor: nextCursor
        }
      })
    };
  } catch (error) {
    console.error('数据库查询失败:', error);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: '服务器内部错误' })
    };
  } finally {
    if (connection) {
      await connection.end();
    }
  }
};

关键注意事项

  • 两种方案的排序字段必须添加索引,否则大数据量下查询性能会急剧下降
  • 偏移量分页可能出现数据不一致(分页过程中数据被删除/新增),键集分页不存在这个问题
  • 普通后台管理系统用偏移量分页足够,移动端滚动加载或大数据量场景建议用键集分页

内容的提问来源于stack exchange,提问作者Karim Fayed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 19:05:21