Java SDK 按主键范围读取数据表中的连续多行数据,支持正反向读取、按版本范围过滤、按列值过滤,适用于按主键区间批量扫描行数据的场景。
前提条件
安装 Tablestore Java SDK并初始化客户端。
功能说明
public GetRangeResponse getRange(GetRangeRequest getRangeRequest) throws TableStoreException, ClientException按主键范围扫描数据表中的连续多行。通过 RangeRowQueryCriteria 指定起始和结束主键,结果通过 response.getRows() 获取行列表。
以下示例从数据表 get_range_demo 正向读取主键值大于等于 row1 的所有行,仅返回每列最新版本。
String tableName = "get_range_demo";
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
// 起始主键(包含)
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());
// 结束主键(不包含),INF_MAX 表示无限大
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());
criteria.setMaxVersions(1);
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("RequestId: " + response.getRequestId());
System.out.println("Read CU: " + response.getConsumedCapacity().getCapacityUnit().getReadCapacityUnit());
for (Row row : response.getRows()) {
System.out.println(row);
}单次范围扫描数据上限为 5000 行或者 4 MB。超出限制时,响应中的 nextStartPrimaryKey 返回下一页起始主键,需循环调用读取剩余数据。
关键参数:
tableName(必选):读取的数据表名称。
inclusiveStartPrimaryKey(必选):起始主键,包含该主键。
exclusiveEndPrimaryKey(必选):结束主键,不包含该主键。
maxVersions 或 timeRange(二选一):最大版本数或数据版本范围。
参数说明
通过 RangeRowQueryCriteria 携带查询条件,各参数说明如下。
名称 | 类型 | 说明 |
tableName(必选) | String | 读取的数据表名称。 |
inclusiveStartPrimaryKey(必选) | PrimaryKey | 起始主键信息,包括主键列名称和主键值。
|
exclusiveEndPrimaryKey(必选) | PrimaryKey | 结束主键信息,包括主键列名称和主键值。
|
direction(可选) | Direction | 读取方向。
|
maxVersions(二选一) | OptionalValue<Integer> | 最大版本数。 如果符合查询条件的数据版本数量超过设置的最大版本数,按从新到旧的顺序返回指定版本数量的数据。 |
timeRange(二选一) | OptionalValue<TimeRange> | 数据版本范围。 数据表的每个属性列可以有不同的数据版本,设置版本范围后仅返回该范围内的数据。 |
limit(可选) | int | 单次返回最大行数,必须大于 0。 如果符合查询条件的数据行数大于设置的值,返回指定的最大行数和用于下一次查询的起始主键值。 |
columnsToGet(可选) | Set<String> | 指定读取的数据列,可以是主键列或属性列。
|
filter(可选) | OptionalValue<Filter> | 过滤条件,详情请参见过滤器。 如果同时设置 |
场景示例
分页迭代读取
单次响应最多返回 5000 行或 4 MB。响应中的 nextStartPrimaryKey 为下一页起始主键,循环调用直至返回 null 即扫完全部数据。
String tableName = "get_range_demo";
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());
criteria.setMaxVersions(1);
int totalRows = 0;
while (true) {
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
totalRows += response.getRows().size();
// 单次响应未读完,使用 nextStartPrimaryKey 继续下一页
PrimaryKey nextStart = response.getNextStartPrimaryKey();
if (nextStart == null) {
break;
}
criteria.setInclusiveStartPrimaryKey(nextStart);
}
System.out.println("Total rows scanned: " + totalRows);反向读取
通过 setDirection(Direction.BACKWARD) 反向扫描。反向读取时起始主键必须大于结束主键。
String tableName = "get_range_demo";
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
criteria.setDirection(Direction.BACKWARD);
// 反向读取时,起始主键必须大于结束主键
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());
criteria.setMaxVersions(1);
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Rows (backward): " + response.getRows().size());条件过滤读取
通过 setFilter 设置列值过滤条件,仅返回符合条件的行。
String tableName = "get_range_demo";
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());
criteria.setMaxVersions(1);
// 仅返回 col1 等于 "val1" 的行
SingleColumnValueFilter filter = new SingleColumnValueFilter(
"col1",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val1"));
filter.setPassIfMissing(false);
criteria.setFilter(filter);
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Rows (filtered): " + response.getRows().size());