Skip to content

Table API

要操作某个表,需要获取该表的特定视图并调用其方法,只能使用 SQL API 创建表。

Ignite 支持将用户对象映射到表元组,这使得用任何编程语言创建的对象都可以直接用于键-值操作。

1.Ignite3中的表视图

1.1.二进制和非二进制视图

在操作表时,Ignite 提供了两种方法,称为视图:直接处理数据或将数据映射到类。直接处理数据的方法称为二进制视图。而在将数据映射到类时,数据会根据数据库交互的需要在这些类之间进行转换。

1.2.记录视图和键-值视图

创建视图时可以创建RecordViewKeyValueView,这些视图类型之间的主要区别在于使用的 API。

RecordView 中,会创建一个记录,其中包含这一行数据的所有信息,包含所有字段,也包括主键。

KeyValueView 中,可以使用键-值映射。可以将其视为一个字典,其中键对象包含一个或多个主键字段,值对象包含数据字段。当主键与业务对象没有直接关系时,可能不希望将主键加入业务对象,此方法非常有用。

2.获取Table实例

使用IgniteTables.table(String)方法可以获取表的实例,还可以使用IgniteTables.tables()方法列出所有现有表。

java
IgniteTables tableApi = client.tables();
List<Table> existingTables = tableApi.tables();
Table firstTable = existingTables.get(0);

Table myTable = tableApi.table("MY_TABLE");
csharp
var existingTables = await Client.Tables.GetTablesAsync();
var firstTable = existingTables[0];

var myTable = await Client.Tables.GetTableAsync("MY_TABLE");
cpp
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.二进制记录视图

该视图可用于直接操作表元组。从二进制视图中检索数据时,可以使用多种方法来检索存储在元组中的特定类型的数据。

java
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"));
csharp
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");
cpp
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.记录视图

该视图映射到一个业务类型上,可以使用映射到表元组的用户对象来操作表。

java
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);
csharp
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);
cpp
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.二进制键-值视图

该视图可以分别使用键和值元组来操作表。从二进制视图检索数据时,可以使用各种方法来检索存储在元组中的特定类型的数据。

java
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"));
csharp
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");
cpp
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.键-值视图

该视图映射到一个业务类型上,可以使用映射到表元组的键对象和值对象来操作表。

java
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);
csharp
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);
cpp
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 提供了可用于从表中检索数据的条件查询。条件查询适用于任何类型的视图,并返回正确的数据。

下面的示例显示了如何在隐式事务中执行查询:

java
try (Cursor<Map.Entry<Tuple, Tuple>> cursor = kvView.query(
        null,
        and(columnValue("name", equalTo("John Doe")), columnValue("age", greaterThan(20)))
)) {
    // ...
}

通过使用query()方法指定条件查询,并在columnValue方法中提供比较条件。

还可以指定要执行查询的事务,以便在该事务中执行查询。

java
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方法异步执行查询。这样查询的执行不会阻塞线程。例如可以异步执行上述查询:

java
kvView.queryAsync(null, and(columnValue("name", equalTo("John Doe")), columnValue("age", greaterThan(20))))
        .thenCompose(this::fetchAllRowsInto)
        .join();

该操作使用thenCompose()方法在用户定义的fetchAllRowsInto()方法中异步处理查询结果,此方法可能如下所示:

java
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