Java SDK 通過迭代器讀取主鍵範圍內的多行資料,並自動處理底層分批請求和翻頁。
前提條件
安裝 Tablestore Java SDK並初始化用戶端。
功能說明
調用 createRangeIterator 方法建立指定主鍵範圍的行資料迭代器。當前批次的資料耗盡後,迭代器自動發起下一批請求,無需記錄 nextStartPrimaryKey 或迴圈調用 getRange。
public Iterator<Row> createRangeIterator(RangeIteratorParameter rangeIteratorParameter) throws TableStoreException, ClientException
以下樣本從資料表 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);
參數說明
通過 RangeIteratorParameter 攜帶迭代查詢條件,各參數說明如下。
|
名稱 |
類型 |
說明 |
|
tableName(必選) |
String |
讀取的資料表名稱。 |
|
inclusiveStartPrimaryKey(必選) |
PrimaryKey |
起始主鍵資訊,包括主鍵列名稱和主索引值。
|
|
exclusiveEndPrimaryKey(必選) |
PrimaryKey |
結束主鍵資訊,包括主鍵列名稱和主索引值。
|
|
direction(可選) |
Direction |
讀取方向。
|
|
maxVersions(可選) |
OptionalValue<Integer> |
每個屬性列返回的最大版本數。 如果符合查詢條件的資料版本數量超過設定的最大版本數,按從新到舊的順序返回指定版本數量的資料。 |
|
timeRange(可選) |
OptionalValue<TimeRange> |
資料版本範圍。 資料表的每個屬性列可以有不同的資料版本,設定版本範圍後僅返回該範圍內的資料。 |
|
maxCount(可選) |
int |
迭代器返回的最大總行數,必須大於 0。 |
|
bufferSize(可選) |
int |
每次底層請求拉取的行數,必須大於 0。 適當減小此值可降低巨量資料量情境下的記憶體峰值;當前批次資料耗盡後,迭代器自動從上次斷點發起下一次請求。 |
|
columnsToGet(可選) |
Set<String> |
指定讀取的資料列,可以是主鍵列或屬性列。
|
|
filter(可選) |
OptionalValue<Filter> |
過濾條件,詳情請參見過濾器。 如果同時設定 |
傳回值
createRangeIterator 返回 Iterator<Row>。調用 hasNext() 判斷是否仍有資料,調用 next() 擷取下一行 Row 對象。
情境樣本
反向迭代
通過 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);
}