TableStore数据准备:
首先需要添加TableStore的依赖
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>tablestore</artifactId>
<version>4.10.2</version>
</dependency>
运行项目时可能会出现SLF4J相关的红字提示:
该提示不影响使用,如果觉得不爽的话,可以添加下面依赖去除:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.26</version>
</dependency>
TableStore的主键含自增类型,该类型为Interger,但是值很大,不能通过这中自增主键查询数据,因此下面的SDK查询操作都是不允许有自增主键的。
另外。表中的数据操作,对Column或者说属性是有版本号这个概念的,该版本号以时间戳为准。当然,如果属性需要存储多个版本号的数据,在建表的时候要注意最大版本号这么一项,需要设置大于1。
1、根据主键查询数据
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.model.Column;
import com.alicloud.openservices.tablestore.model.GetRowRequest;
import com.alicloud.openservices.tablestore.model.GetRowResponse;
import com.alicloud.openservices.tablestore.model.PrimaryKey;
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
import com.alicloud.openservices.tablestore.model.Row;
import com.alicloud.openservices.tablestore.model.SingleRowQueryCriteria;
public class Query {
public static void main(String[] args) {
final String endPoint = "实例访问地址";
final String accessKeyId = "accessKeyId";
final String accessKeySecret = "accessKeySecret";
// 实例名
final String instanceName = "owlforest";
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(1));
PrimaryKey primaryKey = primaryKeyBuilder.build();
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("note", primaryKey);
// 设置读取最新版本
criteria.setMaxVersions(1);
// 读取所有数据
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
// 遍历所有列
Column[] columns = row.getColumns();
for (Column column : columns) {
System.out.println("Name:" + column.getName() + " Value:" + column.getValue());
}
}
}
如果只需要读取指定列,可以这样设置:
// 设置读取某些列
String[] a = { "author" };
criteria.addColumnsToGet(a);
GetRowResponse getRowResponse2 = client.getRow(new GetRowRequest(criteria));
Row row2 = getRowResponse2.getRow();
Column[] columns2 = row2.getColumns();
for (Column column : columns2) {
System.out.println("Name:" + column.getName() + " Value:" + column.getValue());
}
经测试,criteria.addColumnsToGet("author");这么设置运行也不会报错,不过仍然会读出所有属性。
2、根据主键查询数据-设置过滤器
可以表示的列与值的比较关系包括:EQUAL(=), NOT_EQUAL(!=), GREATER_THAN(>), GREATER_EQUAL(>=), LESS_THAN(<)以及LESS_EQUAL(<=)。
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(1));
PrimaryKey primaryKey = primaryKeyBuilder.build();
// 读一行
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("note", primaryKey);
// 设置读取最新版本
criteria.setMaxVersions(1);
//设置过滤器
SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
"author", CompareOperator.EQUAL, ColumnValue.fromString("I am zhangsan"));
//如果不存在此列,也不返回
singleColumnValueFilter.setPassIfMissing(false);
criteria.setFilter(singleColumnValueFilter);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
if(row != null) {
Column[] columns = row.getColumns();
for(Column column : columns) {
System.out.println("Name:" + column.getName() + " Value:" + column.getValue() + "\n");
}
}else {
System.out.println("Row为空");
}
3、根据主键修改一行数据
修改前
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(1));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowUpdateChange rowUpdateChange = new RowUpdateChange("note", primaryKey);
//修改author属性
rowUpdateChange.put(new Column("author", ColumnValue.fromString("我叫张三")));
//新增属性阅读量view
rowUpdateChange.put(new Column("view", ColumnValue.fromLong(10)));
//删除title属性
rowUpdateChange.deleteColumns("title");
// 删除某列的某一版本
//rowUpdateChange.deleteColumn(属性名, 版本号);
UpdateRowResponse response = client.updateRow(new UpdateRowRequest(rowUpdateChange));
修改后
4、新增一行数据
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(1));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange("note", primaryKey);
long ts = System.currentTimeMillis();
rowPutChange.addColumn(new Column("year", ColumnValue.fromLong(2019), ts));
rowPutChange.addColumn(new Column("month", ColumnValue.fromLong(3), ts));
rowPutChange.addColumn(new Column("day", ColumnValue.fromString("天"), ts + 1));
rowPutChange.addColumn(new Column("day", ColumnValue.fromString("日"), ts + 2));
client.putRow(new PutRowRequest(rowPutChange));
note表当中原先就有一条noteid为1的数据,执行PutRow之后,发现原数据被新数据直接覆盖了。
5、期望原行不存在时写入
经测试:当主键1存在时,添加条件RowExistenceExpectation.EXPECT_NOT_EXIST,执行PutRow会出现异常Failed RetriedCount:0 [ErrorCode]:OTSConditionCheckFail, [Message]:Condition check failed.
如果构造的主键不存在于数据库,则可以正常插入。这个条件的使用场景比较让人费解,先记下,兴许后续会用上。
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
try {
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(1));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange("note", primaryKey);
rowPutChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_NOT_EXIST));
rowPutChange.addColumn(new Column("attr", ColumnValue.fromString("主键为1,看不到我"),System.currentTimeMillis()));
client.putRow(new PutRowRequest(rowPutChange));
} catch (Exception e) {
System.out.println(e.getMessage());
}
6、期望存在并某属性满足某条件时,覆盖写入行
同上,满足条件是覆盖该主键的数据,否则出错
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(2));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange("note", primaryKey);
try {
// 期望原行存在,且属性year=2019时插入
Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
condition.setColumnCondition(
new SingleColumnValueCondition("year", CompareOperator.EQUAL, ColumnValue.fromLong(2019)));
rowPutChange.setCondition(condition);
rowPutChange.addColumn(new Column("attr", ColumnValue.fromString("2019年")));
client.putRow(new PutRowRequest(rowPutChange));
} catch (Exception e) {
System.out.println(e.getMessage());
}
7、删除一行数据
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(10));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowDeleteChange rowDeleteChange = new RowDeleteChange("note", primaryKey);
client.deleteRow(new DeleteRowRequest(rowDeleteChange));
8、根据条件删除数据
SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
// 构造主键
try {
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("noteid", PrimaryKeyValue.fromLong(1));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowDeleteChange rowDeleteChange = new RowDeleteChange("note", primaryKey);
Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
condition.setColumnCondition(new SingleColumnValueCondition("year",
SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(2019)));
rowDeleteChange.setCondition(condition);
client.deleteRow(new DeleteRowRequest(rowDeleteChange));
} catch (Exception e) {
System.out.println(e.getMessage());
}