Skip to content

Java API

本章节会介绍如何将 Java 程序接入 Ignite 3 集群,演示使用 Ignite Java API 处理数据的要点。

1.前提条件

  • JDK 17 或更高的版本;
  • Maven;
  • Docker 和 Docker Compose 的最新版本。

2.设置 Ignite 3 集群

创建一个 Docker Compose 文件来运行一个三节点的 Ignite 集群:

yml
# docker-compose.yml
name: ignite3

x-ignite-def: &ignite-def
  image: apacheignite/ignite:3.1.0
  environment:
    JVM_MAX_MEM: "4g"
    JVM_MIN_MEM: "4g"
  configs:
    - source: node_config
      target: /opt/ignite/etc/ignite-config.conf

services:
  node1:
    <<: *ignite-def
    command: --node-name node1
    ports:
      - "10300:10300"  # REST API port
      - "10800:10800"  # Client port
  node2:
    <<: *ignite-def
    command: --node-name node2
    ports:
      - "10301:10300"
      - "10801:10800"
  node3:
    <<: *ignite-def
    command: --node-name node3
    ports:
      - "10302:10300"
      - "10802:10800"

configs:
  node_config:
    content: |
      ignite {
        network {
          port: 3344
          nodeFinder.netClusterNodes = ["node1:3344", "node2:3344", "node3:3344"]
        }
      }

2.1.启动和初始化集群

  1. 启动集群:
    shell
    docker compose up -d
  2. 运行 Ignite 命令行并初始化集群:
    shell
    docker run --rm -it --network=host -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 apacheignite/ignite:3.1.0 cli
  3. 在命令行中,确认已接入默认的节点。
  4. 初始化集群:
    shell
    cluster init --name=ignite3
  5. 进入 SQL 模式:
    shell
    sql
  6. 创建示例表并插入数据:
    sql
    CREATE TABLE Person (id INT PRIMARY KEY, name VARCHAR);
    INSERT INTO Person (id, name) VALUES (1, 'John');
  7. 退出 SQL 模式和命令行工具:
    shell
    exit;
    exit

3.设置 Java 工程

3.1.创建 Maven 工程

首先,创建一个简单的 Maven 工程,以下是后面将使用的工程示例:

ignite3-java-demo/
├── pom.xml
└── src/
    └── main/
        └── java/
            └── com/
                └── example/
                    └── Main.java

3.2.配置 Maven 依赖

pom.xml文件中包含 Ignite 客户端依赖:

xml
<dependencies>
    <!-- Ignite 3 Client -->
    <dependency>
        <groupId>org.apache.ignite</groupId>
        <artifactId>ignite-client</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

4.构建 Java 程序

下一步将创建一个接入 Ignite 集群并执行各种数据操作的 Java 程序。

4.1.主程序类

创建一个Main.java,代码如下:

提示

该文件的位置,请参见上面的结构示例,此示例包含完整的类文件。

java
package com.example;

import org.apache.ignite.catalog.ColumnType;
import org.apache.ignite.catalog.definitions.ColumnDefinition;
import org.apache.ignite.catalog.definitions.TableDefinition;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.table.KeyValueView;
import org.apache.ignite.table.RecordView;
import org.apache.ignite.table.Table;
import org.apache.ignite.table.Tuple;

/**
 * This example demonstrates connecting to an Ignite 3 cluster
 * and working with data using different table view patterns.
 */
public class Main {
    public static void main(String[] args) {
        // Create an array of connection addresses for fault tolerance
        String[] addresses = {
                "localhost:10800",
                "localhost:10801",
                "localhost:10802"
        };

        // Connect to the Ignite cluster using the client builder pattern
        try (IgniteClient client = IgniteClient.builder()
                .addresses(addresses)
                .build()) {

            System.out.println("Connected to the cluster: " + client.connections());

            // Demonstrate querying existing data using SQL API
            queryExistingTable(client);

            // Create a new table using Java API
            Table table = createTable(client);

            // Demonstrate different ways to interact with tables
            populateTableWithDifferentViews(table);

            // Query the new table using SQL API
            queryNewTable(client);
        }
    }

    /**
     * Queries the pre-created Person table using SQL
     */
    private static void queryExistingTable(IgniteClient client) {
        System.out.println("\n--- Querying Person table ---");
        client.sql().execute(null, "SELECT * FROM Person")
                .forEachRemaining(row -> System.out.println("Person: " + row.stringValue("name")));
    }

    /**
     * Creates a new table using the Java API
     */
    private static Table createTable(IgniteClient client) {
        System.out.println("\n--- Creating Person2 table ---");
        return client.catalog().createTable(
                TableDefinition.builder("Person2")
                        .ifNotExists()
                        .columns(
                                ColumnDefinition.column("ID", ColumnType.INT32),
                                ColumnDefinition.column("NAME", ColumnType.VARCHAR))
                        .primaryKey("ID")
                        .build());
    }

    /**
     * Demonstrates different ways to interact with tables
     */
    private static void populateTableWithDifferentViews(Table table) {
        System.out.println("\n--- Populating Person2 table using different views ---");

        // 1. Using RecordView with Tuples
        RecordView<Tuple> recordView = table.recordView();
        recordView.upsert(null, Tuple.create().set("id", 2).set("name", "Jane"));
        System.out.println("Added record using RecordView with Tuple");

        // 2. Using RecordView with POJOs
        RecordView<Person> pojoView = table.recordView(Person.class);
        pojoView.upsert(null, new Person(3, "Jack"));
        System.out.println("Added record using RecordView with POJO");

        // 3. Using KeyValueView with Tuples
        KeyValueView<Tuple, Tuple> keyValueView = table.keyValueView();
        keyValueView.put(null, Tuple.create().set("id", 4), Tuple.create().set("name", "Jill"));
        System.out.println("Added record using KeyValueView with Tuples");

        // 4. Using KeyValueView with Native Types
        KeyValueView<Integer, String> keyValuePojoView = table.keyValueView(Integer.class, String.class);
        keyValuePojoView.put(null, 5, "Joe");
        System.out.println("Added record using KeyValueView with Native Types");
    }

    /**
     * Queries the newly created Person2 table using SQL
     */
    private static void queryNewTable(IgniteClient client) {
        System.out.println("\n--- Querying Person2 table ---");
        client.sql().execute(null, "SELECT * FROM Person2")
                .forEachRemaining(row -> System.out.println("Person2: " + row.stringValue("name")));
    }

    /**
     * POJO class representing a Person
     */
    public static class Person {
        // Default constructor required for serialization
        public Person() { }

        public Person(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        Integer id;
        String name;
    }
}

5.运行程序

按照如下步骤运行该程序:

  1. 确认 Ignite 集群已启动并运行;
  2. 编译并运行该 Java 程序:
    shell
    mvn compile exec:java -Dexec.mainClass="com.example.Main"

6.预期输出

大致会看到以下内容的输出:

Connected to the cluster: Connections{active=1, total=1}

--- Querying Person table ---
Person: John

--- Creating Person2 table ---

--- Populating Person2 table using different views ---
Added record using RecordView with Tuple
Added record using RecordView with POJO
Added record using KeyValueView with Tuples
Added record using KeyValueView with Native Types

--- Querying Person2 table ---
Person2: Jane
Person2: Jack
Person2: Jill
Person2: Joe

7.了解 Ignite 3 中的表视图

Ignite 3 除了提供可靠的 SQL API 之外,还提供了多种视图模式,用于与表交互。下面的示例展示了如何在没有 SQL 的情况下使用工程中的 Ignite 表。有关使用 SQL 的示例,请参阅 SQL 入门章节的内容。

7.1.RecordView 模式

RecordView 将表视为记录的集合,非常适合处理整行的操作:

java
// Get RecordView for Tuple objects (schema-less)
RecordView<Tuple> recordView = table.recordView();
recordView.upsert(null, Tuple.create().set("id", 2).set("name", "Jane"));

// Get RecordView for mapped POJO objects (type-safe)
RecordView<Person> pojoView = table.recordView(Person.class);
pojoView.upsert(null, new Person(3, "Jack"));

7.2.KeyValueView 模式

KeyValueView 将表视为键-值对存储,非常适合简单查找:

java
// Get KeyValueView for Tuple objects
KeyValueView<Tuple, Tuple> keyValueView = table.keyValueView();
keyValueView.put(null, Tuple.create().set("id", 4), Tuple.create().set("name", "Jill"));

// Get KeyValueView for native Java types
KeyValueView<Integer, String> keyValuePojoView = table.keyValueView(Integer.class, String.class);
keyValuePojoView.put(null, 5, "Joe");

8.清理

执行如下的操作可以停止集群:

shell
docker compose down

9.故障排除

如果遇到了连接问题:

  • 使用docker compose ps命令验证 Docker 容器是否正在运行;
  • 检查暴露的端口是否与客户端配置中的端口匹配;
  • 确认localhost接口可以访问 Docker 容器网络。

10.下一步

现在已经演示了接入 Ignite 并与操作数据的基础知识,之后可以:

  • 尝试实现事务;
  • 尝试更复杂的模式和数据类型;
  • 了解数据分区策略;
  • 研究分布式计算功能。

18624049226