Table API
要操作某个表,需要获取该表的特定视图并调用其方法,只能使用 SQL API 创建表。
Ignite 支持将用户对象映射到表元组,这使得用任何编程语言创建的对象都可以直接用于键-值操作。
1.Ignite3中的表视图
1.1.二进制和非二进制视图
在操作表时,Ignite 提供了两种方法,称为视图:直接处理数据或将数据映射到类。直接处理数据的方法称为二进制视图。而在将数据映射到类时,数据会根据数据库交互的需要在这些类之间进行转换。
1.2.记录视图和键-值视图
创建视图时可以创建RecordView
或KeyValueView
,这些视图类型之间的主要区别在于使用的 API。
在 RecordView
中,会创建一个记录
,其中包含这一行数据的所有信息,包含所有字段,也包括主键。
在 KeyValueView
中,可以使用键-值映射。可以将其视为一个字典,其中键对象包含一个或多个主键字段,值对象包含数据字段。当主键与业务对象没有直接关系时,可能不希望将主键加入业务对象,此方法非常有用。
2.获取Table实例
使用IgniteTables.table(String)
方法可以获取表的实例,还可以使用IgniteTables.tables()
方法列出所有现有表。
IgniteTables tableApi = client.tables();
List<Table> existingTables = tableApi.tables();
Table firstTable = existingTables.get(0);
Table myTable = tableApi.table("MY_TABLE");
var existingTables = await Client.Tables.GetTablesAsync();
var firstTable = existingTables[0];
var myTable = await Client.Tables.GetTableAsync("MY_TABLE");
using namespace ignite;
auto table_api = client.get_tables();
std::vector<table> existing_tables = table_api.get_tables();
table first_table = existing_tables.front();
std::optional<table> my_table = table_api.get_table("MY_TABLE);
3.Table的基本操作
拿到Table
实例后,就需要选择一个视图来确定如何操作数据。
3.1.二进制记录视图
该视图可用于直接操作表元组。从二进制视图中检索数据时,可以使用多种方法来检索存储在元组中的特定类型的数据。
RecordView<Tuple> view = myTable.recordView();
//create a new person record
Tuple fullRecord = Tuple.create()
.set("id", 42)
.set("name", "John Doe");
view.upsert(null, fullRecord);
//create a key to find record with id = 42
Tuple keyRecord = Tuple.create().set("id", 42);
Tuple resultRecord = view.get(null, keyRecord);
System.out.println("id: " + resultRecord.intValue("id"));
System.out.println("name: " + resultRecord.stringValue("name"));
IRecordView<IIgniteTuple> view = table.RecordBinaryView;
IIgniteTuple fullRecord = new IgniteTuple
{
["id"] = 42,
["name"] = "John Doe"
};
await view.UpsertAsync(transaction: null, fullRecord);
IIgniteTuple keyRecord = new IgniteTuple { ["id"] = 42 };
(IIgniteTuple value, bool hasValue) = await view.GetAsync(transaction: null, keyRecord);
Debug.Assert(hasValue);
Debug.Assert(value.FieldCount == 2);
Debug.Assert(value["id"] as int? == 42);
Debug.Assert(value["name"] as string == "John Doe");
record_view<ignite_tuple> view = table.get_record_binary_view();
ignite_tuple record{
{"id", 42},
{"name", "John Doe"}
};
view.upsert(nullptr, record);
std::optional<ignite_tuple> res_record = view.get(nullptr, {"id", 42});
assert(res_record.has_value());
assert(res_record->column_count() == 2);
assert(res_record->get<std::int64_t>("id") == 42);
assert(res_record->get<std::string>("name") == "John Doe");
3.2.记录视图
该视图映射到一个业务类型上,可以使用映射到表元组的用户对象来操作表。
RecordView<Person> personView = myTable.recordView(Mapper.of(Person.class));
//insert a new Person object
personView.upsert(null, new Person(42, "John Doe", 30));
//retrieve the Person object with id = 42
Person resultRecord = personView.get(null, new Person(42, "Jane Doe", 32));
System.out.println("id: " + resultRecord.id);
System.out.println("name:" + resultRecord.name);
var pocoView = table.GetRecordView<Poco>();
await pocoView.UpsertAsync(transaction: null, new Poco(42, "John Doe"));
var (value, hasValue) = await pocoView.GetAsync(transaction: null, new Poco(42));
Debug.Assert(hasValue);
Debug.Assert(value.Name == "John Doe");
public record Poco(long Id, string? Name = null);
record_view<person> view = table.get_record_view<person>();
person record(42, "John Doe");
view.upsert(nullptr, record);
std::optional<person> res_record = view.get(nullptr, person{42});
assert(res.has_value());
assert(res->id == 42);
assert(res->name == "John Doe");
3.3.二进制键-值视图
该视图可以分别使用键和值元组来操作表。从二进制视图检索数据时,可以使用各种方法来检索存储在元组中的特定类型的数据。
KeyValueView<Tuple, Tuple> kvView = myTable.keyValueView();
Tuple key = Tuple.create().set("id", 42);
Tuple val = Tuple.create().set("name", "John Doe").set("age", 30);
kvView.put(null, key, val);
Tuple resultRecord = kvView.get(null, key);
System.out.println("age: " + resultRecord.intValue("age"));
System.out.println("name: " + resultRecord.stringValue("name"));
IKeyValueView<IIgniteTuple, IIgniteTuple> kvView = table.KeyValueBinaryView;
IIgniteTuple key = new IgniteTuple { ["id"] = 42 };
IIgniteTuple val = new IgniteTuple { ["name"] = "John Doe" };
await kvView.PutAsync(transaction: null, key, val);
(IIgniteTuple? value, bool hasValue) = await kvView.GetAsync(transaction: null, key);
Debug.Assert(hasValue);
Debug.Assert(value.FieldCount == 1);
Debug.Assert(value["name"] as string == "John Doe");
key_value_view<ignite_tuple, ignite_tuple> kv_view = table.get_key_value_binary_view();
ignite_tuple key_tuple{{"id", 42}};
ignite_tuple val_tuple{{"name", "John Doe"}};
kv_view.put(nullptr, key_tuple, val_tuple);
std::optional<ignite_tuple> res_tuple = kv_view.get(nullptr, key_tuple);
assert(res_tuple.has_value());
assert(res_tuple->column_count() == 2);
assert(res_tuple->get<std::int64_t>("id") == 42);
assert(res_tuple->get<std::string>("name") == "John Doe");
3.4.键-值视图
该视图映射到一个业务类型上,可以使用映射到表元组的键对象和值对象来操作表。
KeyValueView<Integer, PersonKV> personView =
myTable.keyValueView(Mapper.of(Integer.class), Mapper.of(PersonKV.class));
personView.put(null, 42, new PersonKV("John Doe", 30));
PersonKV val = personView.get(null, 42);
System.out.println("name: " + val.name);
IKeyValueView<long, Poco> kvView = table.GetKeyValueView<long, Poco>();
await kvView.PutAsync(transaction: null, 42, new Poco(Id: 0, Name: "John Doe"));
(Poco? value, bool hasValue) = await kvView.GetAsync(transaction: null, 42);
Debug.Assert(hasValue);
Debug.Assert(value.Name == "John Doe");
public record Poco(long Id, string? Name = null);
key_value_view<person, person> kv_view = table.get_key_value_view<person, person>();
kv_view.put(nullptr, {42}, {"John Doe"});
std::optional<person> res = kv_view.get(nullptr, {42});
assert(res.has_value());
assert(res->id == 42);
assert(res->name == "John Doe");
4.条件查询
Ignite 3 提供了可用于从表中检索数据的条件查询。条件查询适用于任何类型的视图,并返回正确的数据。
下面的示例显示了如何在隐式事务中执行查询:
try (Cursor<Map.Entry<Tuple, Tuple>> cursor = kvView.query(
null,
and(columnValue("name", equalTo("John Doe")), columnValue("age", greaterThan(20)))
)) {
// ...
}
通过使用query()
方法指定条件查询,并在columnValue
方法中提供比较条件。
还可以指定要执行查询的事务,以便在该事务中执行查询。
Ignite client = node.api();
Transaction tx = client.transactions().begin();
try (Cursor<Map.Entry<Tuple, Tuple>> cursor = kvView.query(
tx,
and(columnValue("name", equalTo("John Doe")), columnValue("age", greaterThan(20)))
)) {
// ...
}
tx.commit();
4.1.异步查询
还可以使用queryAsync
方法异步执行查询。这样查询的执行不会阻塞线程。例如可以异步执行上述查询:
kvView.queryAsync(null, and(columnValue("name", equalTo("John Doe")), columnValue("age", greaterThan(20))))
.thenCompose(this::fetchAllRowsInto)
.join();
该操作使用thenCompose()
方法在用户定义的fetchAllRowsInto()
方法中异步处理查询结果,此方法可能如下所示:
public CompletionStage<Void> fetchAllRowsInto(AsyncCursor<Map.Entry<Tuple, Tuple>> cursor) {
// Process the current page.
for (var row : cursor.currentPage()) {
// ...
}
// Finish processing if no more data is currently available.
if (!cursor.hasMorePages()) {
return CompletableFuture.completedFuture(null);
}
// Request for the next page, then subscribe to the response.
return cursor.fetchNextPage().thenCompose(this::fetchAllRowsInto);
}
4.2.比较表达式
条件查询支持以下表达式:
表达式 | 描述 | 示例 |
---|---|---|
equalTo | 检查对象是否等于该值。 | columnValue("City", equalTo("New York")) |
notEqualTo | 检查对象是否不等于该值。 | columnValue("City", notEqualTo("New York")) |
greaterThan | 检查对象是否大于该值。 | columnValue("Salary", greaterThan(10000)) |
greaterThanOrEqualTo | 检查对象是否大于或等于该值。 | columnValue("Salary", greaterThanOrEqualTo(10000)) |
lessThan | 检查对象是否小于该值。 | columnValue("Salary", lessThan(10000)) |
lessThanOrEqualTo | 检查对象是否小于或等于该值。 | columnValue("Salary", lessThanOrEqualTo(10000)) |
nullValue | 检查对象是否为空。 | columnValue("City", nullValue() |
notNullValue | 检查对象是否不为空。 | columnValue("City", notNullValue()) |
in | 检查对象是否在集合中。 | columnValue("City", in("New York", "Washington")) |
notIn | 检查对象是否不在集合中。 | columnValue("City", notIn("New York", "Washington")) |
4.3.比较运算符
条件查询支持以下运算符:
表达式 | 描述 | 示例 |
---|---|---|
not | 取非运算符 | not(columnValue("City", equalTo("New York"))) |
and | 取和运算符 | and(columnValue("City", equalTo("New York")), columnValue("Salary", greaterThan(10000))) |
or | 取或运算符 | or(columnValue("City", equalTo("New York")), columnValue("Salary", greaterThan(10000))) |
18624049226