tableStore更新時,必須有PK
總結:
這個東西本身可能技術還不成熟,使用的人少,有問題很難解決
遇到的問題:
(1)沒有一個GUI工具,使用門檻高
(2)查詢的GetRange不方便,把查詢出來的數據使用System.out.println打印出來的是亂碼
(3)batch insert時報錯及解析:
表格存儲Table Store限制項:https://help.aliyun.com/knowledge_detail/38573.html
BatchGetRow 一次操作請求讀取的行數 不超過 100 N/A
BatchWriteRow 一次操作請求寫入行數 不超過 200 N/A
BatchWriteRow 一次操作的數據大小 不超過 4 MB N/A
GetRange 一次返回的數據 5000 行或者 4 MB 一次返回數據的行數超過 5000 行,或者返回數據的數據大小大於 4 MB。以上任一條件滿足時,超出上限的數據將會按行級別被截掉並返回下一行數據主鍵信息
一次 HTTP 請求 Request Body 的數據大小 不超過 5 MB
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>tablestore</artifactId> <version>4.2.1</version> </dependency>
2017-05-18 18:14:55.520 ERROR [http-nio-5000-exec-1]com.xiaoyi.app.tool.car.service.BatchService -/862442030078001_2378171_1.2.0_1493620263150.tar.gz,contentLength:2238,Rows count exceeds the upper limit: 200.
com.alicloud.openservices.tablestore.TableStoreException: Rows count exceeds the upper limit: 200.
at com.alicloud.openservices.tablestore.core.CallbackImpledFuture.getResultWithoutLock(CallbackImpledFuture.java:107)
at com.alicloud.openservices.tablestore.core.CallbackImpledFuture.get(CallbackImpledFuture.java:78)
at com.alicloud.openservices.tablestore.SyncClient.waitForFuture(SyncClient.java:249)
at com.alicloud.openservices.tablestore.SyncClient.batchWriteRow(SyncClient.java:187)
at com.xiaoyi.app.business.car.biz.CarGpsBiz.insertList(CarGpsBiz.java:61)
at com.xiaoyi.app.business.car.biz.CarGpsBiz$$FastClassBySpringCGLIB$$c43f0f59.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at com.xiaoyi.app.core.car.aop.CatAspect.doServerAround(CatAspect.java:46)
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.xiaoyi.app.business.car.biz.CarGpsBiz$$EnhancerBySpringCGLIB$$6c9a8019.insertList(<generated>)
at com.xiaoyi.app.tool.car.service.BatchService.handle(BatchService.java:86)
at com.xiaoyi.app.tool.car.restful.GatherController.gatherOss(GatherController.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.dianping.cat.servlet.CatFilter$Context.handle(CatFilter.java:332)
at com.dianping.cat.servlet.CatFilter$CatHandler$2.handle(CatFilter.java:120)
at com.dianping.cat.servlet.CatFilter$Context.handle(CatFilter.java:330)
at com.dianping.cat.servlet.CatFilter$CatHandler$3.handle(CatFilter.java:137)
at com.dianping.cat.servlet.CatFilter$Context.handle(CatFilter.java:330)
at com.dianping.cat.servlet.CatFilter$CatHandler$4.handle(CatFilter.java:266)
at com.dianping.cat.servlet.CatFilter$Context.handle(CatFilter.java:330)
at com.dianping.cat.servlet.CatFilter$CatHandler$1.handle(CatFilter.java:73)
at com.dianping.cat.servlet.CatFilter$Context.handle(CatFilter.java:330)
at com.dianping.cat.servlet.CatFilter.doFilter(CatFilter.java:40)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.alicloud.openservices.tablestore.TableStoreException: Rows count exceeds the upper limit: 200.
at com.alicloud.openservices.tablestore.core.http.ErrorResponseHandler.handle(ErrorResponseHandler.java:56)
at com.alicloud.openservices.tablestore.core.http.ResponseConsumer.getResponseContentWithMeta(ResponseConsumer.java:95)
at com.alicloud.openservices.tablestore.core.http.BatchWriteRowResponseConsumer.parseResult(BatchWriteRowResponseConsumer.java:65)
at com.alicloud.openservices.tablestore.core.http.BatchWriteRowResponseConsumer.parseResult(BatchWriteRowResponseConsumer.java:18)
at com.alicloud.openservices.tablestore.core.http.ResponseConsumer.buildResult(ResponseConsumer.java:74)
at org.apache.http.nio.protocol.AbstractAsyncResponseConsumer.responseCompleted(AbstractAsyncResponseConsumer.java:157)
at org.apache.http.impl.nio.client.MainClientExec.responseCompleted(MainClientExec.java:383)
at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:172)
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.processResponse(HttpAsyncRequestExecutor.java:437)
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.inputReady(HttpAsyncRequestExecutor.java:327)
at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:265)
at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81)
at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588)
... 1 common frames omitted
2017-05-18 18:16:30.430 ERROR [http-nio-5000-exec-1
如何高效存儲海量GPS數據:https://yq.aliyun.com/articles/74460
從SQL到NoSQL—如何使用表格存儲 https://yq.aliyun.com/articles/64411
使用MaxCompute訪問TableStore(OTS) 簡明手冊 https://yq.aliyun.com/articles/72075
表格存儲數據模型和查詢操作 https://yq.aliyun.com/articles/38621
sdk:
表操作:https://help.aliyun.com/document_detail/43012.html?spm=5176.doc43017.6.692.FqI5C4
多行數據操作:https://help.aliyun.com/document_detail/43017.html
主鍵列自增:https://help.aliyun.com/document_detail/47731.html?spm=5176.doc43012.6.697.MeAkYn
最佳實踐,表操作:https://help.aliyun.com/document_detail/27356.html?spm=5176.2020520106.122.1.mc3CbL
最佳實踐,過濾器:https://helpcdn.aliyun.com/document_detail/35193.html?spm=5176.doc35194.6.594.A3mFNT
api 多行數據操作: https://help.aliyun.com/document_detail/43017.html?spm=5176.doc27283.6.694.tZydZm
api表格存儲:GetRange https://help.aliyun.com/document_detail/27309.html?spm=5176.doc27304.6.629.S7OXV5
import com.alicloud.openservices.tablestore.ClientConfiguration; import com.alicloud.openservices.tablestore.ClientException; import com.alicloud.openservices.tablestore.SyncClient; import com.alicloud.openservices.tablestore.TableStoreException; import com.alicloud.openservices.tablestore.model.*; import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueFilter; import com.xiaoyi.app.business.car.biz.CarGpsBiz; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.List; /** * Created by tang.cheng on 2017/5/18. */ @Component public class TableStoreUtil { private static final String TABLE_NAME = "tt_test"; private static final String PRIMARY_KEY_NAME = "pk_id"; private static final Logger LOGGER = LoggerFactory.getLogger(TableStoreUtil.class); public static void main(String[] args) throws InterruptedException { final String endPoint = ""; final String accessKeyId = ""; final String accessKeySecret = ""; final String instanceName = "tt_test_instance"; // ClientConfiguration提供了很多配置項,以下只列舉部分。 ClientConfiguration clientConfiguration = new ClientConfiguration(); // 設置建立連接的超時時間。 clientConfiguration.setConnectionTimeoutInMillisecond(5000); // 設置socket超時時間。 clientConfiguration.setSocketTimeoutInMillisecond(5000); // 設置重試策略,若不設置,采用默認的重試策略。 clientConfiguration.setRetryStrategy(new AlwaysRetryStrategy()); SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName, clientConfiguration); try { // createTable(client, CarGpsBiz.TABLE_NAME); batchRange(client, CarGpsBiz.TABLE_NAME); // deleteTable(client, CarGpsBiz.TABLE_NAME); /* createTable(client); TimeUnit.SECONDS.sleep(10);*/ // listTable(client); // describeTable(client); // deleteTable(client,"sampleTable"); // deleteTable(client,"sampleTable2"); /* batchWriteRow(client); System.out.println("==============batchGetRow=============="); batchGetRow(client);*/ } catch (TableStoreException e) { System.err.println("操作失敗,詳情:" + e.getMessage()); System.err.println("Request ID:" + e.getRequestId()); } catch (ClientException e) { System.err.println("請求失敗,詳情:" + e.getMessage()); } catch (Exception e) { e.printStackTrace(); } finally { // deleteTable(client); } } public static void batchRange(SyncClient client, String tableName) { // 等同於 SELECT * FROM UserHistory WHERE user_id = '10100' RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(tableName); // 設置起始主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); String imei = "/862442030051651"; primaryKeyBuilder.addPrimaryKeyColumn("partition_key", PrimaryKeyValue.INF_MIN); primaryKeyBuilder.addPrimaryKeyColumn("imei", PrimaryKeyValue.INF_MIN); primaryKeyBuilder.addPrimaryKeyColumn("time", PrimaryKeyValue.INF_MIN); primaryKeyBuilder.addPrimaryKeyColumn("tid", PrimaryKeyValue.INF_MIN); rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build()); // 設置結束主鍵 primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn("partition_key", PrimaryKeyValue.INF_MAX); primaryKeyBuilder.addPrimaryKeyColumn("imei", PrimaryKeyValue.INF_MAX); primaryKeyBuilder.addPrimaryKeyColumn("time", PrimaryKeyValue.INF_MAX); primaryKeyBuilder.addPrimaryKeyColumn("tid", PrimaryKeyValue.INF_MAX); rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build()); // 設置讀取最新版本 rangeRowQueryCriteria.setMaxVersions(1); // 默認讀取所有的屬性列 GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria)); List<Row> rows = getRangeResponse.getRows(); System.out.println("rows size:" + rows.size()); for (int i = 0; i < 2; i++) { for (Column column : rows.get(i).getColumns()) { LOGGER.info("{},{}", column.getName(), column.getValue()); } } } public static void createTable(SyncClient client, String tableName) { TableMeta tableMeta = new TableMeta(tableName); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("partition_key", PrimaryKeyType.STRING)); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("imei", PrimaryKeyType.STRING)); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("time", PrimaryKeyType.INTEGER)); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("tid", PrimaryKeyType.INTEGER)); int timeToLive = 182 * 24 * 3600; // 數據的過期時間, 單位秒, -1代表永不過期. 假如設置過期時間為一年, 即為 365 * 24 * 3600. int maxVersions = 3; // 保存的最大版本數, 設置為3即代表每列上最多保存3個最新的版本. TableOptions tableOptions = new TableOptions(timeToLive, maxVersions); CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions); client.createTable(request); } public static void listTable(SyncClient client) { ListTableResponse response = client.listTable(); System.out.println("表的列表如下:"); for (String tableName : response.getTableNames()) { System.out.println(tableName); } } public static void deleteTable(SyncClient client, String tableName) { DeleteTableRequest request = new DeleteTableRequest(tableName); client.deleteTable(request); } public static void describeTable(SyncClient client) { DescribeTableRequest request = new DescribeTableRequest(TABLE_NAME); DescribeTableResponse response = client.describeTable(request); TableMeta tableMeta = response.getTableMeta(); System.out.println("表的名稱:" + tableMeta.getTableName()); System.out.println("表的主鍵:"); for (PrimaryKeySchema primaryKeySchema : tableMeta.getPrimaryKeyList()) { System.out.println(primaryKeySchema); } TableOptions tableOptions = response.getTableOptions(); System.out.println("表的TTL:" + tableOptions.getTimeToLive()); System.out.println("表的MaxVersions:" + tableOptions.getMaxVersions()); ReservedThroughputDetails reservedThroughputDetails = response.getReservedThroughputDetails(); System.out.println("表的預留讀吞吐量:" + reservedThroughputDetails.getCapacityUnit().getReadCapacityUnit()); System.out.println("表的預留寫吞吐量:" + reservedThroughputDetails.getCapacityUnit().getWriteCapacityUnit()); } public static void batchWriteRow(SyncClient client) { BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest(); // 構造rowPutChange1 PrimaryKeyBuilder pk1Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk1Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk1")); RowPutChange rowPutChange1 = new RowPutChange(TABLE_NAME, pk1Builder.build()); // 添加一些列 for (int i = 0; i < 10; i++) { rowPutChange1.addColumn(new Column("Col" + i, ColumnValue.fromLong(i))); } // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowPutChange1); // 構造rowPutChange2 PrimaryKeyBuilder pk2Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk2Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk2")); RowPutChange rowPutChange2 = new RowPutChange(TABLE_NAME, pk2Builder.build()); // 添加一些列 for (int i = 0; i < 10; i++) { rowPutChange2.addColumn(new Column("Col" + i, ColumnValue.fromLong(i))); } // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowPutChange2); // 構造rowUpdateChange PrimaryKeyBuilder pk3Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk3Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk3")); RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, pk3Builder.build()); // 添加一些列 for (int i = 0; i < 10; i++) { rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i))); } // 刪除一列 rowUpdateChange.deleteColumns("Col10"); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowUpdateChange); // 構造rowDeleteChange PrimaryKeyBuilder pk4Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk4Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk4")); RowDeleteChange rowDeleteChange = new RowDeleteChange(TABLE_NAME, pk4Builder.build()); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowDeleteChange); BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest); System.out.println("是否全部成功:" + response.isAllSucceed()); if (!response.isAllSucceed()) { for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) { System.out.println("失敗的行:" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey()); System.out.println("失敗原因:" + rowResult.getError()); } /** * 可以通過createRequestForRetry方法再構造一個請求對失敗的行進行重試.這里只給出構造重試請求的部分. * 推薦的重試方法是使用SDK的自定義重試策略功能, 支持對batch操作的部分行錯誤進行重試. 設定重試策略后, 調用接口處即不需要增加重試代碼. */ BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows()); } } private static void batchGetRow(SyncClient client) { MultiRowQueryCriteria multiRowQueryCriteria = new MultiRowQueryCriteria(TABLE_NAME); // 加入10個要讀取的行 for (int i = 0; i < 10; i++) { PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk" + i)); PrimaryKey primaryKey = primaryKeyBuilder.build(); multiRowQueryCriteria.addRow(primaryKey); } // 添加條件 multiRowQueryCriteria.setMaxVersions(1); multiRowQueryCriteria.addColumnsToGet("Col0"); multiRowQueryCriteria.addColumnsToGet("Col1"); SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0)); singleColumnValueFilter.setPassIfMissing(false); multiRowQueryCriteria.setFilter(singleColumnValueFilter); BatchGetRowRequest batchGetRowRequest = new BatchGetRowRequest(); // batchGetRow支持讀取多個表的數據, 一個multiRowQueryCriteria對應一個表的查詢條件, 可以添加多個multiRowQueryCriteria. batchGetRowRequest.addMultiRowQueryCriteria(multiRowQueryCriteria); BatchGetRowResponse batchGetRowResponse = client.batchGetRow(batchGetRowRequest); System.out.println("是否全部成功:" + batchGetRowResponse.isAllSucceed()); if (!batchGetRowResponse.isAllSucceed()) { for (BatchGetRowResponse.RowResult rowResult : batchGetRowResponse.getFailedRows()) { System.out.println("失敗的行:" + batchGetRowRequest.getPrimaryKey(rowResult.getTableName(), rowResult.getIndex())); System.out.println("失敗原因:" + rowResult.getError()); } /** * 可以通過createRequestForRetry方法再構造一個請求對失敗的行進行重試.這里只給出構造重試請求的部分. * 推薦的重試方法是使用SDK的自定義重試策略功能, 支持對batch操作的部分行錯誤進行重試. 設定重試策略后, 調用接口處即不需要增加重試代碼. */ BatchGetRowRequest retryRequest = batchGetRowRequest.createRequestForRetry(batchGetRowResponse.getFailedRows()); } } }
demo1:
import com.alicloud.openservices.tablestore.ClientException; import com.alicloud.openservices.tablestore.SyncClient; import com.alicloud.openservices.tablestore.TableStoreException; import com.alicloud.openservices.tablestore.model.*; /** * Created by yizheng on 16/4/28. */ public class TableOperationSample { /** * 本示例中建立一張表,名為sampleTable,只含有一個主鍵, 主鍵名為pk. */ private static final String TABLE_NAME = "sampleTable2"; private static final String PRIMARY_KEY_NAME = "pk"; public static void main(String[] args) { final String endPoint = ""; final String accessId = ""; final String accessKey = ""; final String instanceName = ""; SyncClient client = new SyncClient(endPoint, accessId, accessKey, instanceName); try { // 創建表 createTable(client); // list table查看表的列表 listTable(client); // 查看表的屬性 describeTable(client); // 更新表的屬性 updateTable(client); // update table完之后查看表的屬性 describeTable(client); // list table查看表的列表 listTable(client); } catch (TableStoreException e) { System.err.println("操作失敗,詳情:" + e.getMessage()); System.err.println("Request ID:" + e.getRequestId()); } catch (ClientException e) { System.err.println("請求失敗,詳情:" + e.getMessage()); } client.shutdown(); } public static void createTable(SyncClient client) { TableMeta tableMeta = new TableMeta(TABLE_NAME); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME, PrimaryKeyType.STRING)); int timeToLive = -1; // 數據的過期時間, 單位秒, -1代表永不過期. 假如設置過期時間為一年, 即為 365 * 24 * 3600. int maxVersions = 3; // 保存的最大版本數, 設置為3即代表每列上最多保存3個最新的版本. TableOptions tableOptions = new TableOptions(timeToLive, maxVersions); CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions); client.createTable(request); } public static void updateTable(SyncClient client) { int timeToLive = -1; int maxVersions = 5; //更新最大版本數為5. TableOptions tableOptions = new TableOptions(timeToLive, maxVersions); UpdateTableRequest request = new UpdateTableRequest(TABLE_NAME); request.setTableOptionsForUpdate(tableOptions); client.updateTable(request); } public static void describeTable(SyncClient client) { DescribeTableRequest request = new DescribeTableRequest(TABLE_NAME); DescribeTableResponse response = client.describeTable(request); TableMeta tableMeta = response.getTableMeta(); System.out.println("表的名稱:" + tableMeta.getTableName()); System.out.println("表的主鍵:"); for (PrimaryKeySchema primaryKeySchema : tableMeta.getPrimaryKeyList()) { System.out.println(primaryKeySchema); } TableOptions tableOptions = response.getTableOptions(); System.out.println("表的TTL:" + tableOptions.getTimeToLive()); System.out.println("表的MaxVersions:" + tableOptions.getMaxVersions()); ReservedThroughputDetails reservedThroughputDetails = response.getReservedThroughputDetails(); System.out.println("表的預留讀吞吐量:" + reservedThroughputDetails.getCapacityUnit().getReadCapacityUnit()); System.out.println("表的預留寫吞吐量:" + reservedThroughputDetails.getCapacityUnit().getWriteCapacityUnit()); } public static void deleteTable(SyncClient client) { DeleteTableRequest request = new DeleteTableRequest(TABLE_NAME); client.deleteTable(request); } public static void listTable(SyncClient client) { ListTableResponse response = client.listTable(); System.out.println("表的列表如下:"); for (String tableName : response.getTableNames()) { System.out.println(tableName); } } }
demo2
import com.alicloud.openservices.tablestore.ClientException; import com.alicloud.openservices.tablestore.SyncClient; import com.alicloud.openservices.tablestore.TableStoreException; import com.alicloud.openservices.tablestore.model.*; import com.alicloud.openservices.tablestore.model.condition.ColumnCondition; import com.alicloud.openservices.tablestore.model.condition.SingleColumnValueCondition; import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueFilter; import java.util.Iterator; public class PkAutoIncrSample { /** * 本示例中建立一張表,名為sampleTable,兩個主鍵, 主鍵分別為pk1,pk2. */ private static final String TABLE_NAME = "sampleTable_pk"; private static final String PRIMARY_KEY_NAME_1 = "pk1"; private static final String PRIMARY_KEY_NAME_2 = "pk2"; public static void main(String[] args) { final String endPoint = ""; final String accessId = ""; final String accessKey = ""; final String instanceName = ""; SyncClient client = new SyncClient(endPoint, accessId, accessKey, instanceName); try { // 建表 createTable(client); System.out.println("create table succeeded."); // 等待表load完畢. try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } // putRow PrimaryKey pk = putRow(client); System.out.println("put row succeeded,pk:" + pk.toString()); // getRow getRow(client, pk); // updateRow updateRow(client, pk); getRowWithFilter(client, pk); // 使用condition遞增一列 updateRowWithCondition(client, pk); // getRow getRow(client, pk); // 再寫入兩行 putRow(client); putRow(client); // getRange getRange(client, "a", "z"); // 使用iterator進行getRange getRangeByIterator(client, "a", "z"); batchWriteRow(client); } catch (TableStoreException e) { System.err.println("操作失敗,詳情:" + e.getMessage()); System.err.println("Request ID:" + e.getRequestId()); } catch (ClientException e) { System.err.println("請求失敗,詳情:" + e.getMessage()); } finally { // 為了安全,這里不能默認刪表,如果需要刪表,需用戶自己手動打開 // deleteTable(client); } client.shutdown(); } private static void createTable(SyncClient client) { TableMeta tableMeta = new TableMeta(TABLE_NAME); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME_1, PrimaryKeyType.STRING)); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME_2, PrimaryKeyType.INTEGER, PrimaryKeyOption.AUTO_INCREMENT)); int timeToLive = -1; // 數據的過期時間, 單位秒, -1代表永不過期. 假如設置過期時間為一年, 即為 365 * 24 * 3600. int maxVersions = 1; // 保存的最大版本數, 設置為1即代表每列上最多保存一個版本(保存最新的版本). TableOptions tableOptions = new TableOptions(timeToLive, maxVersions); CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions); client.createTable(request); } private static void deleteTable(SyncClient client) { DeleteTableRequest request = new DeleteTableRequest(TABLE_NAME); client.deleteTable(request); } private static PrimaryKey putRow(SyncClient client) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString("chengdu")); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.AUTO_INCRMENT); PrimaryKey primaryKey = primaryKeyBuilder.build(); RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey); rowPutChange.setReturnType(ReturnType.RT_PK); //加入一些屬性列 long ts = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j)); } } PutRowResponse response = client.putRow(new PutRowRequest(rowPutChange)); // 打印出消耗的CU CapacityUnit cu = response.getConsumedCapacity().getCapacityUnit(); System.out.println("Read CapacityUnit:" + cu.getReadCapacityUnit()); System.out.println("Write CapacityUnit:" + cu.getWriteCapacityUnit()); // 打印出返回的PK列 PrimaryKey pk = response.getRow().getPrimaryKey(); System.out.println("PrimaryKey:" + pk.toString()); return pk; } private static void updateRow(SyncClient client, PrimaryKey pk) { RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, pk); // 更新一些列 for (int i = 0; i < 10; i++) { rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i))); } // 刪除某列的某一版本 rowUpdateChange.deleteColumn("Col10", 1465373223000L); // 刪除某一列 rowUpdateChange.deleteColumns("Col11"); rowUpdateChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_EXIST)); client.updateRow(new UpdateRowRequest(rowUpdateChange)); } private static void deleteRow(SyncClient client, PrimaryKey pk) { RowDeleteChange rowDeleteChange = new RowDeleteChange(TABLE_NAME, pk); client.deleteRow(new DeleteRowRequest(rowDeleteChange)); } private static void batchWriteRow(SyncClient client) { BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest(); // 構造rowPutChange1 PrimaryKeyBuilder pk1Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk1Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString("Hangzhou")); pk1Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.AUTO_INCRMENT); RowPutChange rowPutChange1 = new RowPutChange(TABLE_NAME, pk1Builder.build()); rowPutChange1.setReturnType(ReturnType.RT_PK); // 添加一些列 rowPutChange1.addColumn(new Column("Column_0", ColumnValue.fromLong(99))); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowPutChange1); // 構造rowPutChange2 PrimaryKeyBuilder pk2Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk2Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString("Hangzhou")); pk2Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.AUTO_INCRMENT); RowPutChange rowPutChange2 = new RowPutChange(TABLE_NAME, pk2Builder.build()); rowPutChange2.setReturnType(ReturnType.RT_PK); // 添加一些列 rowPutChange2.addColumn(new Column("Column_0", ColumnValue.fromLong(100))); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowPutChange2); // 構造rowUpdateChange PrimaryKeyBuilder pk3Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk3Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString("Hangzhou")); pk3Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.AUTO_INCRMENT); RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, pk3Builder.build()); rowUpdateChange.setReturnType(ReturnType.RT_PK); // 添加一列 rowUpdateChange.put(new Column("Column_0", ColumnValue.fromLong(101))); // 刪除一列 rowUpdateChange.deleteColumns("Column_1"); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowUpdateChange); // 構造rowDeleteChange PrimaryKeyBuilder pk4Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk4Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString("Hangzhou")); pk4Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(1)); RowDeleteChange rowDeleteChange = new RowDeleteChange(TABLE_NAME, pk4Builder.build()); rowDeleteChange.setReturnType(ReturnType.RT_PK); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowDeleteChange); BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest); System.out.println("是否全部成功:" + response.isAllSucceed()); if (!response.isAllSucceed()) { for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) { System.out.println("失敗的行:" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey()); System.out.println("失敗原因:" + rowResult.getError()); } /* * 可以通過createRequestForRetry方法再構造一個請求對失敗的行進行重試.這里只給出構造重試請求的部分. * 推薦的重試方法是使用SDK的自定義重試策略功能, 支持對batch操作的部分行錯誤進行重試. 設定重試策略后, 調用接口處即不需要增加重試代碼. */ BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows()); } else { for (BatchWriteRowResponse.RowResult rowResult : response.getSucceedRows()) { PrimaryKey pk = rowResult.getRow().getPrimaryKey(); System.out.println("Return PK:" + pk.jsonize()); } } } private static void getRow(SyncClient client, PrimaryKey pk) { // 讀一行 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, pk); // 設置讀取最新版本 criteria.setMaxVersions(1); GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria)); Row row = getRowResponse.getRow(); System.out.println("讀取完畢, 結果為: "); System.out.println(row); // 設置讀取某些列 criteria.addColumnsToGet("Col0"); getRowResponse = client.getRow(new GetRowRequest(criteria)); row = getRowResponse.getRow(); System.out.println("讀取完畢, 結果為: "); System.out.println(row); } private static void getRowWithFilter(SyncClient client, PrimaryKey pk) { // 讀一行 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, pk); // 設置讀取最新版本 criteria.setMaxVersions(1); // 設置過濾器, 當Col0的值為0時返回該行. SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0)); // 如果不存在Col0這一列, 也不返回. singleColumnValueFilter.setPassIfMissing(false); // 只判斷最新版本 singleColumnValueFilter.setLatestVersionsOnly(true); criteria.setFilter(singleColumnValueFilter); GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria)); Row row = getRowResponse.getRow(); System.out.println("讀取完畢, 結果為: "); System.out.println(row); } // 通過Condition實現樂觀鎖機制, 遞增一列. private static void updateRowWithCondition(SyncClient client, PrimaryKey pk) { // 讀一行 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, pk); criteria.setMaxVersions(1); GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria)); Row row = getRowResponse.getRow(); long col0Value = row.getLatestColumn("Col0").getValue().asLong(); // 條件更新Col0這一列, 使列值+1 RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, pk); Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST); ColumnCondition columnCondition = new SingleColumnValueCondition("Col0", SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(col0Value)); condition.setColumnCondition(columnCondition); rowUpdateChange.setCondition(condition); rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value + 1))); try { client.updateRow(new UpdateRowRequest(rowUpdateChange)); } catch (TableStoreException ex) { System.out.println(ex.toString()); } } private static void getRange(SyncClient client, String startPkValue, String endPkValue) { RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME); // 設置起始主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString(startPkValue)); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(0)); rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build()); // 設置結束主鍵 primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString(endPkValue)); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX); rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build()); rangeRowQueryCriteria.setMaxVersions(1); System.out.println("GetRange的結果為:"); while (true) { GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria)); for (Row row : getRangeResponse.getRows()) { System.out.println(row); } // 若nextStartPrimaryKey不為null, 則繼續讀取. if (getRangeResponse.getNextStartPrimaryKey() != null) { rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey()); } else { break; } } } private static void getRangeByIterator(SyncClient client, String startPkValue, String endPkValue) { RangeIteratorParameter rangeIteratorParameter = new RangeIteratorParameter(TABLE_NAME); // 設置起始主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString(startPkValue)); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(0)); rangeIteratorParameter.setInclusiveStartPrimaryKey(primaryKeyBuilder.build()); // 設置結束主鍵 primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString(endPkValue)); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX); rangeIteratorParameter.setExclusiveEndPrimaryKey(primaryKeyBuilder.build()); rangeIteratorParameter.setMaxVersions(1); Iterator<Row> iterator = client.createRangeIterator(rangeIteratorParameter); System.out.println("使用Iterator進行GetRange的結果為:"); while (iterator.hasNext()) { Row row = iterator.next(); System.out.println(row); } } }
demo3
import com.alicloud.openservices.tablestore.ClientException; import com.alicloud.openservices.tablestore.SyncClient; import com.alicloud.openservices.tablestore.TableStoreException; import com.alicloud.openservices.tablestore.model.*; import com.alicloud.openservices.tablestore.model.condition.ColumnCondition; import com.alicloud.openservices.tablestore.model.condition.SingleColumnValueCondition; import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueFilter; import java.util.Iterator; public class DataOperationSample { /** * 本示例中建立一張表,名為sampleTable,只含有一個主鍵, 主鍵名為pk. */ private static final String TABLE_NAME = "sampleTable"; private static final String PRIMARY_KEY_NAME = "pk"; public static void main(String[] args) { final String endPoint = ""; final String accessId = ""; final String accessKey = ""; final String instanceName = ""; SyncClient client = new SyncClient(endPoint, accessId, accessKey, instanceName); try { // 建表 createTable(client); // 等待表load完畢. try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } // putRow putRow(client, "pkValue"); // getRow getRow(client, "pkValue"); // updateRow updateRow(client, "pkValue"); // 使用condition遞增一列 updateRowWithCondition(client, "pkValue"); // getRow getRow(client, "pkValue"); // 再寫入兩行 putRow(client, "aaa"); putRow(client, "bbb"); // getRange getRange(client, "a", "z"); // 使用iterator進行getRange getRangeByIterator(client, "a", "z"); batchWriteRow(client); batchGetRow(client); } catch (TableStoreException e) { System.err.println("操作失敗,詳情:" + e.getMessage()); System.err.println("Request ID:" + e.getRequestId()); } catch (ClientException e) { System.err.println("請求失敗,詳情:" + e.getMessage()); } finally { // 為了安全,這里不能默認刪表,如果需要刪表,需用戶自己手動打開 // deleteTable(client); } client.shutdown(); } private static void createTable(SyncClient client) { TableMeta tableMeta = new TableMeta(TABLE_NAME); tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME, PrimaryKeyType.STRING)); int timeToLive = -1; // 數據的過期時間, 單位秒, -1代表永不過期. 假如設置過期時間為一年, 即為 365 * 24 * 3600. int maxVersions = 1; // 保存的最大版本數, 設置為1即代表每列上最多保存一個版本(保存最新的版本). TableOptions tableOptions = new TableOptions(timeToLive, maxVersions); CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions); client.createTable(request); } private static void deleteTable(SyncClient client) { DeleteTableRequest request = new DeleteTableRequest(TABLE_NAME); client.deleteTable(request); } private static void putRow(SyncClient client, String pkValue) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey); //加入一些屬性列 long ts = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j)); } } client.putRow(new PutRowRequest(rowPutChange)); } private static void updateRow(SyncClient client, String pkValue) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey); // 更新一些列 for (int i = 0; i < 10; i++) { rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i))); } // 刪除某列的某一版本 rowUpdateChange.deleteColumn("Col10", 1465373223000L); // 刪除某一列 rowUpdateChange.deleteColumns("Col11"); client.updateRow(new UpdateRowRequest(rowUpdateChange)); } private static void deleteRow(SyncClient client, String pkValue) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); RowDeleteChange rowDeleteChange = new RowDeleteChange(TABLE_NAME, primaryKey); client.deleteRow(new DeleteRowRequest(rowDeleteChange)); } public static void batchWriteRow(SyncClient client) { BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest(); // 構造rowPutChange1 PrimaryKeyBuilder pk1Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk1Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk1")); RowPutChange rowPutChange1 = new RowPutChange(TABLE_NAME, pk1Builder.build()); // 添加一些列 for (int i = 0; i < 10; i++) { rowPutChange1.addColumn(new Column("Col" + i, ColumnValue.fromLong(i))); } // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowPutChange1); // 構造rowPutChange2 PrimaryKeyBuilder pk2Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk2Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk2")); RowPutChange rowPutChange2 = new RowPutChange(TABLE_NAME, pk2Builder.build()); // 添加一些列 for (int i = 0; i < 10; i++) { rowPutChange2.addColumn(new Column("Col" + i, ColumnValue.fromLong(i))); } // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowPutChange2); // 構造rowUpdateChange PrimaryKeyBuilder pk3Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk3Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk3")); RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, pk3Builder.build()); // 添加一些列 for (int i = 0; i < 10; i++) { rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i))); } // 刪除一列 rowUpdateChange.deleteColumns("Col10"); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowUpdateChange); // 構造rowDeleteChange PrimaryKeyBuilder pk4Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); pk4Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk4")); RowDeleteChange rowDeleteChange = new RowDeleteChange(TABLE_NAME, pk4Builder.build()); // 添加到batch操作中 batchWriteRowRequest.addRowChange(rowDeleteChange); BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest); System.out.println("是否全部成功:" + response.isAllSucceed()); if (!response.isAllSucceed()) { for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) { System.out.println("失敗的行:" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey()); System.out.println("失敗原因:" + rowResult.getError()); } /** * 可以通過createRequestForRetry方法再構造一個請求對失敗的行進行重試.這里只給出構造重試請求的部分. * 推薦的重試方法是使用SDK的自定義重試策略功能, 支持對batch操作的部分行錯誤進行重試. 設定重試策略后, 調用接口處即不需要增加重試代碼. */ BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows()); } } private static void getRow(SyncClient client, String pkValue) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); // 讀一行 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey); // 設置讀取最新版本 criteria.setMaxVersions(1); GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria)); Row row = getRowResponse.getRow(); System.out.println("讀取完畢, 結果為: "); System.out.println(row); // 設置讀取某些列 criteria.addColumnsToGet("Col0"); getRowResponse = client.getRow(new GetRowRequest(criteria)); row = getRowResponse.getRow(); System.out.println("讀取完畢, 結果為: "); System.out.println(row); } private static void getRowWithFilter(SyncClient client, String pkValue) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); // 讀一行 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey); // 設置讀取最新版本 criteria.setMaxVersions(1); // 設置過濾器, 當Col0的值為0時返回該行. SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0)); // 如果不存在Col0這一列, 也不返回. singleColumnValueFilter.setPassIfMissing(false); // 只判斷最新版本 singleColumnValueFilter.setLatestVersionsOnly(true); criteria.setFilter(singleColumnValueFilter); GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria)); Row row = getRowResponse.getRow(); System.out.println("讀取完畢, 結果為: "); System.out.println(row); } private static void batchGetRow(SyncClient client) { MultiRowQueryCriteria multiRowQueryCriteria = new MultiRowQueryCriteria(TABLE_NAME); // 加入10個要讀取的行 for (int i = 0; i < 10; i++) { PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk" + i)); PrimaryKey primaryKey = primaryKeyBuilder.build(); multiRowQueryCriteria.addRow(primaryKey); } // 添加條件 multiRowQueryCriteria.setMaxVersions(1); multiRowQueryCriteria.addColumnsToGet("Col0"); multiRowQueryCriteria.addColumnsToGet("Col1"); SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0)); singleColumnValueFilter.setPassIfMissing(false); multiRowQueryCriteria.setFilter(singleColumnValueFilter); BatchGetRowRequest batchGetRowRequest = new BatchGetRowRequest(); // batchGetRow支持讀取多個表的數據, 一個multiRowQueryCriteria對應一個表的查詢條件, 可以添加多個multiRowQueryCriteria. batchGetRowRequest.addMultiRowQueryCriteria(multiRowQueryCriteria); BatchGetRowResponse batchGetRowResponse = client.batchGetRow(batchGetRowRequest); System.out.println("是否全部成功:" + batchGetRowResponse.isAllSucceed()); if (!batchGetRowResponse.isAllSucceed()) { for (BatchGetRowResponse.RowResult rowResult : batchGetRowResponse.getFailedRows()) { System.out.println("失敗的行:" + batchGetRowRequest.getPrimaryKey(rowResult.getTableName(), rowResult.getIndex())); System.out.println("失敗原因:" + rowResult.getError()); } /** * 可以通過createRequestForRetry方法再構造一個請求對失敗的行進行重試.這里只給出構造重試請求的部分. * 推薦的重試方法是使用SDK的自定義重試策略功能, 支持對batch操作的部分行錯誤進行重試. 設定重試策略后, 調用接口處即不需要增加重試代碼. */ BatchGetRowRequest retryRequest = batchGetRowRequest.createRequestForRetry(batchGetRowResponse.getFailedRows()); } } // 通過Condition實現樂觀鎖機制, 遞增一列. private static void updateRowWithCondition(SyncClient client, String pkValue) { // 構造主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); // 讀一行 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey); criteria.setMaxVersions(1); GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria)); Row row = getRowResponse.getRow(); long col0Value = row.getLatestColumn("Col0").getValue().asLong(); // 條件更新Col0這一列, 使列值+1 RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey); Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST); ColumnCondition columnCondition = new SingleColumnValueCondition("Col0", SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(col0Value)); condition.setColumnCondition(columnCondition); rowUpdateChange.setCondition(condition); rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value + 1))); try { client.updateRow(new UpdateRowRequest(rowUpdateChange)); } catch (TableStoreException ex) { System.out.println(ex.toString()); } } private static void getRange(SyncClient client, String startPkValue, String endPkValue) { RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME); // 設置起始主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(startPkValue)); rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build()); // 設置結束主鍵 primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(endPkValue)); rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build()); rangeRowQueryCriteria.setMaxVersions(1); System.out.println("GetRange的結果為:"); while (true) { GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria)); for (Row row : getRangeResponse.getRows()) { System.out.println(row); } // 若nextStartPrimaryKey不為null, 則繼續讀取. if (getRangeResponse.getNextStartPrimaryKey() != null) { rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey()); } else { break; } } } private static void getRangeByIterator(SyncClient client, String startPkValue, String endPkValue) { RangeIteratorParameter rangeIteratorParameter = new RangeIteratorParameter(TABLE_NAME); // 設置起始主鍵 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(startPkValue)); rangeIteratorParameter.setInclusiveStartPrimaryKey(primaryKeyBuilder.build()); // 設置結束主鍵 primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(endPkValue)); rangeIteratorParameter.setExclusiveEndPrimaryKey(primaryKeyBuilder.build()); rangeIteratorParameter.setMaxVersions(1); Iterator<Row> iterator = client.createRangeIterator(rangeIteratorParameter); System.out.println("使用Iterator進行GetRange的結果為:"); while (iterator.hasNext()) { Row row = iterator.next(); System.out.println(row); } } }