全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网
表格存储

多行数据操作

更新时间:2017-06-07 13:26:11

表格存储的 SDK 提供了 BatchGetRow、BatchWriteRow、GetRange 和 GetByIterator 等多行操作的接口。

批量读(BatchGetRow)

批量读取一个或多个表中的若干行数据。

BatchGetRow 操作可视为多个 GetRow 操作的集合,各个操作独立执行,独立返回结果,独立计算服务能力单元。

与执行大量的 GetRow 操作相比,使用 BatchGetRow 操作可以有效减少请求的响应时间,提高数据的读取速率。

接口

  1. /**
  2. * 从多张表(Table)中获取多行数据。
  3. *
  4. * @param batchGetRowRequest 执行BatchGetRow操作所需参数的封装。
  5. * @return BatchGetRow操作的响应内容。
  6. * @throws OTSException OTS访问返回错误消息
  7. * @throws ClientException 请求的返回结果无效, 或由于网络原因请求失败, 或访问超时。
  8. */
  9. public BatchGetRowResult batchGetRow(BatchGetRowRequest batchGetRowRequest)
  10. throws OTSException, ClientException;

示例

批量一次读 10 行。

  1. try
  2. {
  3. // 构造BatchGetRow对象和参数
  4. BatchGetRowRequest request = new BatchGetRowRequest();
  5. MultiRowQueryCriteria tableRows = new MultiRowQueryCriteria(tableName);
  6. for (int j = 0; j < 10; ++j) {
  7. RowPrimaryKey primaryKeys = new RowPrimaryKey();
  8. primaryKeys.addPrimaryKeyColumn("pk0", PrimaryKeyValue.fromLong(j));
  9. primaryKeys.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromLong(j)));
  10. tableRows.addRow(primaryKeys);
  11. }
  12. // 只返回col0和col1列
  13. tableRows.addColumnsToGet(new String[] {"col0", "col1"});
  14. request.addMultiRowQueryCriteria(tableRows);
  15. // 调用batchGetRow接口
  16. BatchGetRowResult result = client.batchGetRow(request);
  17. // 统计是否有某些行执行失败,如果有,则重试
  18. BatchGetRowRequest failedOperations = null;
  19. List<Row> succeedRows = new ArrayList<Row>();
  20. int retryCount = 0;
  21. do {
  22. failedOperations = new BatchGetRowRequest();
  23. Map<String, List<BatchGetRowResult.RowStatus>> status = result.getTableToRowsStatus();
  24. for (Entry<String, List<BatchGetRowResult.RowStatus>> entry : status.entrySet()) {
  25. tableName = entry.getKey();
  26. tableRows = new MultiRowQueryCriteria(tableName);
  27. List<BatchGetRowResult.RowStatus> statuses = entry.getValue();
  28. for (int index = 0; index < statuses.size(); index++) {
  29. BatchGetRowResult.RowStatus rowStatus = statuses.get(index);
  30. if (!rowStatus.isSucceed()) {
  31. // 操作失败, 需要放到重试列表中再次重试
  32. // 需要重试的操作可以从request中获取参数
  33. tableRows.addRow(request.getPrimaryKey(tableName, index));
  34. } else {
  35. succeedRows.add(rowStatus.getRow());
  36. System.out.println("Read row:");
  37. System.out.println("pk0:" + rowStatus.getRow().getColumns().get("pk0"));
  38. System.out.println("pk1:" + rowStatus.getRow().getColumns().get("pk1"));
  39. System.out.println("col0:" + rowStatus.getRow().getColumns().get("col0"));
  40. }
  41. }
  42. if (!tableRows.getRowKeys().isEmpty()) {
  43. tableRows.addColumnsToGet(new String[] {"col0", "col1"});
  44. failedOperations.addMultiRowQueryCriteria(tableRows);
  45. }
  46. }
  47. if (failedOperations.isEmpty() || ++retryCount > 3) {
  48. // 如果所有操作都成功了或者重试次数达到上线, 则不再需要重试。
  49. break;
  50. }
  51. // 如果有需要重试的操作, 则稍微等待一会后再次重试, 否则继续出错的概率很高。
  52. try {
  53. // 100ms后继续重试
  54. Thread.sleep(100);
  55. } catch (InterruptedException e) {
  56. e.printStackTrace();
  57. }
  58. request = failedOperations;
  59. result = client.batchGetRow(request);
  60. } while (true);
  61. System.out.println(String.format("Get row finish, succeeded count:%d", succeedRows.size()));
  62. } catch (ClientException ex) {
  63. System.out.println("Batch get row failed.");
  64. } catch (OTSException ex) {
  65. System.out.println("Batch get row failed.");
  66. }

提示:

批量写(BatchWriteRow)

批量插入、修改或删除一个或多个表中的若干行数据。

BatchWriteRow 操作可视为多个 PutRow、UpdateRow、DeleteRow 操作的集合,各个操作独立执行,独立返回结果,独立计算服务能力单元。

接口

  1. /**
  2. * 对多张表(Table)中的多行数据进行增加、删除或者更改操作。
  3. *
  4. * @param batchWriteRowRequest 执行BatchWriteRow操作所需参数的封装。
  5. * @return BatchWriteRow操作的响应内容。
  6. * @throws OTSException OTS访问返回错误消息
  7. * @throws ClientException 请求的返回结果无效, 或由于网络原因请求失败, 或访问超时。
  8. */
  9. public BatchWriteRowResult batchWriteRow(
  10. BatchWriteRowRequest batchWriteRowRequest) throws OTSException,
  11. ClientException;

示例

批量导入 30 行数据。

  1. try
  2. {
  3. BatchWriteRowRequest request = new BatchWriteRowRequest();
  4. // 向3张表中插入数据, 每张表插入10行。
  5. for (int i = 0; i < 3; ++i) {
  6. for (int j = 0; j < 10; ++j) {
  7. RowPutChange rowPutChange = new RowPutChange("SampleTable" + i);
  8. RowPrimaryKey primaryKey = new RowPrimaryKey();
  9. primaryKey.addPrimaryKeyColumn("pk0", PrimaryKeyValue.fromLong(i));
  10. primaryKey.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromLong(j));
  11. rowPutChange.setPrimaryKey(primaryKey);
  12. rowPutChange.addAttributeColumn("col0", ColumnValue.fromLong(4));
  13. rowPutChange.addAttributeColumn("col2", ColumnValue.fromString("成杭京"));
  14. request.addRowPutChange(rowPutChange);
  15. }
  16. }
  17. // batchWriteRow接口会返回一个结果集, 结果集中包含的结果个数与插入的行数相同。 结果集中的结果不一定都是成功,用户需要自己对不成功的操作进行重试。
  18. BatchWriteRowResult result = client.batchWriteRow(request);
  19. // 重试逻辑类似于上面的batchGetRow示例中的逻辑,这里省略
  20. } catch (ClientException ex) {
  21. System.out.println("Batch write row failed.");
  22. } catch (OTSException ex) {
  23. System.out.println("Batch write row failed.");
  24. }

提示:

范围读(GetRange)

读取指定主键范围内的数据。

接口

  1. /**
  2. * 从表(Table)中查询一个范围内的多行数据。
  3. *
  4. * @param getRangeRequest 执行GetRange操作所需参数的封装。
  5. * @return GetRange操作的响应内容。
  6. * @throws OTSException OTS访问返回错误消息
  7. * @throws ClientException 请求的返回结果无效, 或由于网络原因请求失败, 或访问超时。
  8. */
  9. public GetRangeResult getRange(GetRangeRequest getRangeRequest)
  10. throws OTSException, ClientException;

示例

按照范围读取。

  1. try
  2. {
  3. // 这里查找uid从1-4(左闭右开)的数据
  4. RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("SampleTable");
  5. RowPrimaryKey inclusiveStartKey = new RowPrimaryKey();
  6. inclusiveStartKey.addPrimaryKeyColumn("pk0", PrimaryKeyValue.fromLong(1));
  7. // 范围的边界需要提供完整的PK,若查询的范围不涉及到某一列值的范围,则需要将该列设置为无穷大或者无穷小
  8. inclusiveStartKey.addPrimaryKeyColumn("pk1", PrimaryKeyValue.INF_MIN);
  9. RowPrimaryKey exclusiveEndKey = new RowPrimaryKey();
  10. exclusiveEndKey.addPrimaryKeyColumn("pk0", PrimaryKeyValue.fromLong(4));
  11. // 范围的边界需要提供完整的PK,若查询的范围不涉及到某一列值的范围,则需要将该列设置为无穷大或者无穷小
  12. exclusiveEndKey.addPrimaryKeyColumn("pk1", PrimaryKeyValue.INF_MAX);
  13. criteria.setInclusiveStartPrimaryKey(inclusiveStartKey);
  14. criteria.setExclusiveEndPrimaryKey(exclusiveEndKey);
  15. // 前向查询
  16. criteria.setDirection(Direction.FORWARD);
  17. // 最多返回10行
  18. criteria.setLimit(10);
  19. // 构造RangeRequest对象
  20. GetRangeRequest request = new GetRangeRequest();
  21. request.setRangeRowQueryCriteria(criteria);
  22. // 调用getRange接口
  23. GetRangeResult result = client.getRange(request);
  24. // 输出数据
  25. List<Row> rows = result.getRows();
  26. for (Row row : rows) {
  27. System.out.println("col0:" + row.getColumns().get("col0"));
  28. System.out.println("col1:" + row.getColumns().get("col1"));
  29. System.out.println("col2:" + row.getColumns().get("col2"));
  30. }
  31. int consumedReadCU = result.getConsumedCapacity().getCapacityUnit().getReadCapacityUnit();
  32. System.out.println("consumed capacityunit:" + consumedReadCU);
  33. System.out.println("Get range succeeded");
  34. } catch (ClientException ex) {
  35. System.out.println("Get range failed.");
  36. } catch (OTSException ex) {
  37. System.out.println("Get range failed.");
  38. }

提示:

  • 按范围读也支持通过条件语句过滤。

  • 详细代码:GetRange@GitHub

迭代读(GetByIterator)

迭代读取数据。

接口

  1. /**
  2. * 从表(Table)中迭代读取满足条件的数据
  3. * @param rangeIteratorParameter
  4. * 迭代读时的参数,包括开始,结束位置
  5. * @return 迭代器
  6. * @throws OTSException
  7. * OTS访问返回错误消息
  8. * @throws ClientException
  9. * 请求的返回结果无效, 或由于网络原因请求失败, 或访问超时。
  10. */
  11. public Iterator<Row> createRangeIterator(
  12. RangeIteratorParameter rangeIteratorParameter)
  13. throws OTSException, ClientException;

示例

迭代读取表 SampleTable 中的数据。

  1. // 构造迭代读取的起始位置
  2. RowPrimaryKey inclusiveStartKey = new RowPrimaryKey();
  3. inclusiveStartKey.addPrimaryKeyColumn(COLUMN_GID_NAME,
  4. PrimaryKeyValue.fromLong(1));
  5. inclusiveStartKey.addPrimaryKeyColumn(COLUMN_UID_NAME,
  6. PrimaryKeyValue.INF_MIN);
  7. // 构造迭代读取的结束位置
  8. RowPrimaryKey exclusiveEndKey = new RowPrimaryKey();
  9. exclusiveEndKey.addPrimaryKeyColumn(COLUMN_GID_NAME,
  10. PrimaryKeyValue.fromLong(4));
  11. exclusiveEndKey.addPrimaryKeyColumn(COLUMN_UID_NAME,
  12. PrimaryKeyValue.INF_MAX);
  13. // 构造迭代读取的参数对象,并设置起始和结束的位置,包括起始位置的行,不包括结束位置的行
  14. RangeIteratorParameter rangeIteratorParameter = new RangeIteratorParameter(tableName);
  15. rangeIteratorParameter.setInclusiveStartPrimaryKey(inclusiveStartKey);
  16. rangeIteratorParameter.setExclusiveEndPrimaryKey(exclusiveEndKey);
  17. // 创建出迭代器,并迭代获取每一行数据
  18. try {
  19. Iterator<Row> iterator = client.createRangeIterator(rangeIteratorParameter);
  20. while (iterator.hasNext()) {
  21. Row row = iterator.next();
  22. System.out.println("name:" + row.getColumns().get(COLUMN_NAME_NAME));
  23. System.out.println("address" + row.getColumns().get(COLUMN_ADDRESS_NAME));
  24. }
  25. System.out.println("Iterator get succeeded.");
  26. } catch (ClientException ex) {
  27. System.out.println("Iterator get failed.");
  28. } catch (OTSException ex) {
  29. System.out.println("Iterator get failed.");
  30. }

提示:

本文导读目录