迭代读取数据

更新时间:
复制 MD 格式

Java SDK 通过迭代器读取主键范围内的多行数据,SDK 自动处理底层分批请求和翻页,适用于大范围扫描需要逐行处理且不希望手动管理翻页的场景。

前提条件

安装 Tablestore Java SDK并初始化客户端。

功能说明

public Iterator<Row> createRangeIterator(RangeIteratorParameter rangeIteratorParameter) throws TableStoreException, ClientException

按主键范围创建迭代器,返回标准 Java Iterator<Row>。每次调用 iterator.next() 时,SDK 透明地从缓冲区取数据并在必要时发起下一批请求,无需手动管理 nextStartPrimaryKey 翻页或循环调用 getRange

以下示例从数据表 range_iter_demo 中主键值 row1 开始正向迭代到表末尾,逐行输出。

String tableName = "range_iter_demo";

RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);

// 起始主键(含)
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());

// 结束主键(不含),INF_MAX 表示读取到表末尾
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());

parameter.setMaxVersions(1);

Iterator<Row> iterator = client.createRangeIterator(parameter);
int count = 0;
while (iterator.hasNext()) {
    Row row = iterator.next();
    System.out.println(row);
    count++;
}
System.out.println("Total rows iterated: " + count);

关键参数

  • tableName(必选):读取的数据表名称。

  • inclusiveStartPrimaryKey(必选):起始主键,包含该主键。

  • exclusiveEndPrimaryKey(必选):结束主键,不包含该主键。

  • maxVersionstimeRange(二选一):最大版本数或数据版本范围。

参数说明

通过 RangeIteratorParameter 携带迭代查询条件,各参数说明如下。

名称

类型

说明

tableName(必选)

String

读取的数据表名称。

inclusiveStartPrimaryKey(必选)

PrimaryKey

起始主键信息,包括主键列名称和主键值。

  • 返回数据包含起始主键。

  • 主键个数和类型必须与数据表的主键 schema 保持一致。

  • 正向迭代时,起始主键必须小于结束主键;反向迭代时,起始主键必须大于结束主键。

  • PrimaryKeyValue.INF_MIN 表示无限小,PrimaryKeyValue.INF_MAX 表示无限大。

exclusiveEndPrimaryKey(必选)

PrimaryKey

结束主键信息,包括主键列名称和主键值。

  • 返回数据不包含结束主键。

  • 主键个数和类型必须与数据表的主键 schema 保持一致。

  • PrimaryKeyValue.INF_MIN 表示无限小,PrimaryKeyValue.INF_MAX 表示无限大。

direction(可选)

Direction

读取方向。

  • FORWARD:默认值,正向迭代。

  • BACKWARD:反向迭代。

maxVersions(二选一)

OptionalValue<Integer>

每个属性列返回的最大版本数。maxVersionstimeRange 必须至少设置一个。

如果符合查询条件的数据版本数量超过设置的最大版本数,按从新到旧的顺序返回指定版本数量的数据。

timeRange(二选一)

OptionalValue<TimeRange>

数据版本范围。maxVersionstimeRange 必须至少设置一个。

数据表的每个属性列可以有不同的数据版本,设置版本范围后仅返回该范围内的数据。

maxCount(可选)

int

迭代器返回的最大总行数,必须大于 0。

bufferSize(可选)

int

每次底层请求拉取的行数,必须大于 0。

适当减小此值可降低大数据量场景下的内存峰值;当前批次数据耗尽后,迭代器自动从上次断点发起下一次请求。

columnsToGet(可选)

Set<String>

指定读取的数据列,可以是主键列或属性列。

  • 不设置 columnsToGet 时,返回整行数据。

  • 设置后如果读取的行数据不包含任何指定的数据列,将返回 null。

filter(可选)

OptionalValue<Filter>

过滤条件,详情请参见过滤器

如果同时设置 columnsToGetfilter,先按 columnsToGet 筛选数据列,再按 filter 条件过滤数据。

场景示例

反向迭代

通过 setDirection(Direction.BACKWARD) 反向迭代。反向迭代时起始主键必须大于结束主键。

String tableName = "range_iter_demo";

RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);
parameter.setDirection(Direction.BACKWARD);

// 反向迭代时,起始主键必须大于结束主键
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());

PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());

parameter.setMaxVersions(1);

Iterator<Row> iterator = client.createRangeIterator(parameter);
while (iterator.hasNext()) {
    Row row = iterator.next();
    System.out.println(row);
}

限制迭代总行数

通过 setMaxCount 限制迭代器最多返回的总行数。适用于按需取 Top N 的场景,避免无意义扫描。

String tableName = "range_iter_demo";

RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);

PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());

PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());

parameter.setMaxVersions(1);
// 最多返回 3 行
parameter.setMaxCount(3);

Iterator<Row> iterator = client.createRangeIterator(parameter);
while (iterator.hasNext()) {
    Row row = iterator.next();
    System.out.println(row);
}

内存优化分批

通过 setBufferSize 控制每次底层请求拉取的行数。适当减小可降低大数据量场景下的内存峰值。

String tableName = "range_iter_demo";

RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);

PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());

PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());

parameter.setMaxVersions(1);
// 每次底层请求拉取 2 行
parameter.setBufferSize(2);

Iterator<Row> iterator = client.createRangeIterator(parameter);
while (iterator.hasNext()) {
    Row row = iterator.next();
    System.out.println(row);
}

相关文档