帮助文档 Logo
平台使用
阿里云
百度云
移动云
智算服务
教育生态
登录 →
帮助文档 Logo
平台使用 阿里云 百度云 移动云 智算服务 教育生态
登录
  1. 首页
  2. 阿里云
  3. 表格存储
  4. 服务支持
  5. 常见问题
  6. APISDK
  7. 如何实现分页查询

如何实现分页查询

  • APISDK
  • 发布于 2025-04-22
  • 0 次阅读
文档编辑
文档编辑

表格存储是一个分布式存储系统,对于查询请求的翻页(分页)有多种方式。本文详细介绍如何实现分页查询。

表

如果只有表,没有多元索引,您可以通过以下方式进行翻页:

重要

通过表主键查询数据时不支持获取整个范围的行数和总页数。

  • 使用nextStartPrimaryKey翻页:每次GetRange请求的Response中会有一个nextStartPrimaryKey,将该nextStartPrimaryKey设置到下一次请求的Request中,即可实现连续翻页。

  • 使用GetRangeIterator迭代器翻页:通过iterator.next()方法持续获取下一条数据。

通过表主键查询数据时不支持使用offset进行跳页查询。如果有业务需要,请在客户端通过nextStartPrimaryKey或Iterator迭代器模拟跳页查询。

多元索引

如果为数据表创建了多元索引,则您可以通过以下方式进行翻页:

重要

通过多元索引查询数据时支持获取总行数和总页数,同时需要在Request中设置getTotalCount为true。其中总行数除以limit的值为总页数。由于设置getTotalCount为true后查询数据时会增大资源消耗,因此查询性能会有所下降。

  • 使用offset+limit方式翻页:支持跳页查询,但是offset+limit最大值不能超过100000。如果超过限制,请使用next_token翻页。

  • 使用next_token翻页:每次Search请求的Response中会有下一次的next_token,将该next_token设置到下一次请求的Request中,即可实现连续翻页。

  • 使用SearchIterator迭代器翻页:通过iterator.next()方法持续获取下一条数据。

表示例

以下示例用于实现一个分页读接口,该接口提供了offset过滤以及读取指定页数的数据。

/**
 * 范围查询指定范围内的数据,返回指定页数大小的数据,并能根据offset跳过部分行。
 */
private static Pair<List<Row>, PrimaryKey> readByPage(SyncClient client, String tableName, 
        PrimaryKey startKey, PrimaryKey endKey, int offset, int pageSize) {
    Preconditions.checkArgument(offset >= 0, "Offset should not be negative.");
    Preconditions.checkArgument(pageSize > 0, "Page size should be greater than 0.");
    List<Row> rows = new ArrayList<Row>(pageSize);
    int limit = pageSize;
    int skip = offset;
    PrimaryKey nextStart = startKey;
    // 如果查询的数据量很大,则一次请求有可能不会返回所有的数据,需要流式查询所有需要的数据。
    while (limit > 0 && nextStart != null) {
        // 构造GetRange的查询参数。
        // 注意:startPrimaryKey需要设置为上一次读到的位点,从上一次未读完的地方继续往下读,实现流式的范围查询。
        RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
        criteria.setInclusiveStartPrimaryKey(nextStart);
        criteria.setExclusiveEndPrimaryKey(endKey);
        criteria.setMaxVersions(1);
        // 需要设置正确的limit,此处期望读出的数据行数最多为完整的一页数据以及需要过滤(offset)的数据。
        criteria.setLimit(skip + limit);
        GetRangeRequest request = new GetRangeRequest();
        request.setRangeRowQueryCriteria(criteria);
        GetRangeResponse response = client.getRange(request);
        for (Row row : response.getRows()) {
            if (skip > 0) {
                skip--; // 对于offset之前的数据,需要过滤掉,采用的策略是读出来后在客户端进行过滤。
            } else {
                rows.add(row);
                limit--;
            }
        }
        // 设置下一次查询的起始位点。
        nextStart = response.getNextStartPrimaryKey();
    }
    return new Pair<List<Row>, PrimaryKey>(rows, nextStart);
}          

以下示例用于使用分页读接口实现顺序按页读取某个指定范围内的所有数据。

private static void readByPage(SyncClient client, String tableName) {
        int pageSize = 8;
        int offset = 33;
        PrimaryKeyBuilder primaryKeyBuilder= PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("gid", PrimaryKeyValue.INF_MIN);
        primaryKeyBuilder.addPrimaryKeyColumn("uid", PrimaryKeyValue.INF_MIN);
        PrimaryKey startKey = primaryKeyBuilder.build();
        primaryKeyBuilder= PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("gid", PrimaryKeyValue.INF_MAX);
        primaryKeyBuilder.addPrimaryKeyColumn("uid", PrimaryKeyValue.INF_MAX);
        PrimaryKey endKey = primaryKeyBuilder.build();
        // 读第一页,从范围的offset=33的行开始读起。
        Pair<List<Row>, PrimaryKey> result = readByPage(client, tableName, startKey, endKey, offset, pageSize);
        for (Row row : result.getFirst()) {
            System.out.println(row);
        }
        System.out.println("Total rows count: " + result.getFirst().size());
        // 顺序翻页,读完范围内的所有数据。
        startKey = result.getSecond();
        while (startKey != null) {
            System.out.println("============= start read next page ==============");
            result = readByPage(client, tableName, startKey, endKey, 0, pageSize);
            for (Row row : result.getFirst()) {
                System.out.println(row);
            }
            startKey = result.getSecond();
            System.out.println("Total rows count: " + result.getFirst().size());
        }

    }

多元索引示例

更多信息,请参见排序和翻页。

相关文章

使用Java SDK访问表格存储时出现SocketTimeoutException异常 2025-04-22 14:18

由于网络不通或网络抖动、服务器高负载、客户端Full GC等原因可能会导致客户端访问表格存储超时。当出现客户端访问超时的问题时,您需要通过检查网络连通性、服务器延迟、客户端是否出现Full GC问题等操作来解决该问题。 问题现象 使用Java SDK访问表格存储时出现Unexpected error

Java SDK日志库相关问题 2025-04-22 14:18

表格存储Java SDK使用的是哪个日志库? 表格存储Java SDK依赖的是slf4j,在依赖中默认依赖log4j2作为日志实现库。</

使用SDK时出现Validate PK type fail异常 2025-04-22 14:18

当使用SDK出现Validate PK type fail异常时,请确保设置的主键数据类型和数据表的主键数据类型一致。 问题现象 使用SDK写入数据时出现如下异常:

使用SDK时出现Validate PK size fail异常 2025-04-22 14:18

当使用SDK出现Validate PK size fail异常时,请确保设置的主键个数和数据表的主键个数一致。 问题现象 使用SDK更新数据时出现如下异常:

使用SDK时出现Validate PK name fail异常 2025-04-22 14:18

当使用SDK时出现Validate PK name fail异常时,请确保设置的主键名称与主键顺序和数据表的主键名称与主键顺序一致。 问题现象 使用SDK查询数据时出现如下异常:

使用Java SDK时出现The access key id is invalid异常 2025-04-22 14:18

现象 使用Java SDK时出现如下异常:

目录
Copyright © 2025 your company All Rights Reserved. Powered by 博智数字服务平台.
闽ICP备08105208号-1