---
title: "OBKV-Table 写入数据 - OceanBase 数据库 V4.4.2 | OceanBase 文档中心"
description: OBKV-Table 写入数据 本文档介绍了 OBKV-Table 的写入能力。OBKV-Table Java 客户端支持索引组织表和堆组织表的单行数据写入和批量数据写入。业务可以根据需求选择对应的接口进行数据写入。 支持写入的接口 ObTableClient 有写入能力的接口如下： 接口 说明 注意事项 inser…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库KV 型 - V 4.4.2 LTS

# OBKV-Table 写入数据

更新时间：2026-04-09 14:48:10

[编辑](https://github.com/oceanbase/oceanbase-kv/edit/V4.4.2/zh-CN/100.obkv-table/200.use-of-the-obkv-table-client/150.obkv-table-demo/100.obkv-table-insert.md)  

本文档介绍了 OBKV-Table 的写入能力。OBKV-Table Java 客户端支持索引组织表和堆组织表的单行数据写入和批量数据写入。业务可以根据需求选择对应的接口进行数据写入。

## 支持写入的接口

ObTableClient 有写入能力的接口如下：

| 接口 | 说明 | 注意事项 |
| --- | --- | --- |
| `insert(String tableName)` | 写入一行数据 | 当主键冲突时，会写入失败 |
| `insertOrUpdate(String tableName)` | 写入或更新一行数据 | |
| `replace(String tableName)` | 替换一行数据 | 当旧行不存在时，将写入新行 |
| `put(String tableName)` | 覆盖写一行数据 | - 必须写入每一列 - 表中无索引 - 表中无 lob 类型 - 租户的 `binlog_row_image` 值必须为 `minimal` - 堆组织表不支持 |

## 写入示例

### 准备条件

写入前需要做如下准备：

- 你的 ObTableClient 已经初始化完成。
 - 在你的数据库中已经创建了索引组织表或堆组织表，示例如下：

  ```sql
  -- 索引组织表
  CREATE TABLE IF NOT EXISTS `employees` (
  `employeeId` int NOT NULL,
  `name` varchar(100) NOT NULL,
  `department` varchar(50),
  `position` varchar(50),
  `workYear` int,
  `comment` varchar(100),
  PRIMARY KEY (`employeeId`)
  ) PARTITION BY KEY(`employeeId`) PARTITIONS 97;

  -- 堆组织表
  CREATE TABLE test (
      c1 bigint,
      c2 varchar(20),
      c3 bigint,
      UNIQUE INDEX idx_unique_c1 (c1) -- 创建唯一索引可以加速查询
    ) ORGANIZATION = HEAP PARTITION BY KEY(c1) PARTITIONS 97; -- 通过 ORGANIZATION 参数指定堆表

  ```

其他说明如下：

- 已支持 JSON 类型，具体说明及写入示例请参见 [OBKV-Table 数据类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005280357)。

### 单行写入

下面的示例代码演示了如何使用 ObTableClient 写入单行数据。

#### insert

    索引组织表   堆组织表

示例代码写入了一行数据，主键 `employeeId` 为 `1001`，写入了 4 个属性列。

```java
private static void insertRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey = row().add(colVal("employeeId", 1001));
    Row properties = row().add(colVal("name", "zhangsan"))
        .add(colVal("department", "R&D"))
        .add(colVal("position", "dev"))
        .add(colVal("workYear", 10));
    obkvHandle.insert("employees")
        .setRowKey(rowKey)
        .addMutateRow(properties)
        .execute();
}

```

本示例展示了如何使用 `insert` 接口对堆表进行单行写入。请注意，堆表写入操作必须通过 `setPartitionKey` 接口设置分区键的值，以确保数据正确路由。

```java
@Test
public void testSingleInsert() throws Exception {
    try {
        // 插入数据
        // 注意需要通过 setPartitionKey 设定分区键 c1 的值
        // 也需要通过 addMutateColVal 设定 c1 的值
        MutationResult result = client.insert("test")
            .setPartitionKey(row(colVal("c1", 1000L)))
            .addMutateColVal(colVal("c1", 1000L), colVal("c2", "test1"), colVal("c3", 3000L))
            .execute();

        assertEquals("Insert should affect 1 row", 1, result.getAffectedRows());
        System.out.println("Single insert successful: " + result + " row affected");
    } finally {
        // 清理数据
        truncateTable();
    }
}

```

#### insertOrUpdate

    索引组织表   堆组织表

示例代码演示了如何使用 ObTableClient 写入或更新一行数据，主键 `employeeId` 为 `1001`，写入了 4 个属性列。

```java
private static void insertOrUpdateRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey = row().add(colVal("employeeId", 1001));
    Row properties = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 10));
    obkvHandle.insertOrUpdate("employees")
            .setRowKey(rowKey)
            .addMutateRow(properties)
            .execute();
}

```

本示例展示了如何使用 `insertOrUpdate` 接口对堆表进行单行写入或更新。请注意，堆表写入操作必须通过 `setPartitionKey` 接口设置分区键的值，以确保数据正确路由。

```java
@Test
public void testSingleInsertOrUpdate1() throws Exception {
    try {
        // 插入数据
        // 注意需要通过 setPartitionKey 设定分区键 c1 的值
        // 也需要通过 addMutateColVal 设定 c1 的值
        MutationResult result = client.insertOrUpdate(tableName)
            .setPartitionKey(row(colVal("c1", 1000L)))
            .addMutateColVal(colVal("c1", 1000L), colVal("c2", "test1"), colVal("c3", 3000L))
            .execute();

        assertEquals("Insert should affect 1 row", 1, result.getAffectedRows());
        System.out.println("Single insertOrUpdate successful: " + result + " row affected");
    } finally {
        // 清理数据
        truncateTable();
    }
}

```

#### replace

    索引组织表   堆组织表

示例代码演示了如何使用 ObTableClient 替换一行数据，主键 `employeeId` 为 `1001`，写入了 4 个属性列。

```java
private static void replaceRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey = row().add(colVal("employeeId", 1001));
    Row properties = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 10));
    obkvHandle.replace("employees")
            .setRowKey(rowKey)
            .addMutateRow(properties)
            .execute();
}

```

本示例展示了如何使用 `replace` 接口对堆表进行单行替换。请注意，堆表替换操作必须通过 `setPartitionKey` 接口设置分区键的值，以确保数据正确路由。

```java
@Test
public void testSingleReplace1() throws Exception {
    try {
        // 插入数据
        // 注意需要通过 setPartitionKey 设定分区键 c1 的值
        // 也需要通过 addMutateColVal 设定 c1 的值
        MutationResult result = client.replace(tableName)
            .setPartitionKey(row(colVal("c1", 1000L)))
            .addMutateColVal(colVal("c1", 1000L), colVal("c2", "test1"), colVal("c3", 3000L))
            .execute();

        assertEquals("Insert should affect 1 row", 1, result.getAffectedRows());
        System.out.println("Single replace successful: " + result + " row affected");
    } finally {
        // 清理数据
        truncateTable();
    }
}

```

#### put

#### 注意

该接口不支持堆组织表。

示例代码演示了如何使用 ObTableClient 覆盖写一行数据到索引组织表，主键 `employeeId` 为 `1001`，写入了 4 个属性列。

```java
private static void putRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey = row().add(colVal("employeeId", 1001));
    Row properties = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 1))
            .add(colVal("comment", "new employee"));
    obkvHandle.put("employees")
            .setRowKey(rowKey)
            .addMutateRow(properties)
            .execute();
}

```

### 批量写入

下面的示例代码演示了如何使用 ObTableClient 批量写入数据.

#### batchInsert

    索引组织表   堆组织表

示例代码在一批里写入了 2 行数据，主键 `employeeId` 分别为 `1001` 和 `1002`，每一行都写入了 4 个属性列。

```java
private static void batchInsertRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey1 = row().add(colVal("employeeId", 1001));
    Row rowKey2 = row().add(colVal("employeeId", 1002));
    Row properties1 = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 10));
    Row properties2 = row().add(colVal("name", "lisi"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 5));
    Insert insertOp1 = insert().setRowKey(rowKey1).addMutateRow(properties1);
    Insert insertOp2 = insert().setRowKey(rowKey2).addMutateRow(properties2);
    BatchOperationResult res = obkvHandle.batchOperation("employees")
            .addOperation(insertOp1,insertOp2)
            .execute();
    System.out.println(res.hasError());
}

```

本示例展示了如何使用 `batchInsert` 接口对堆表进行批量写入。请注意，堆表写入操作必须通过 `setPartitionKey` 接口设置分区键的值，以确保数据正确路由。

```java
@Test
public void testBatchInsert() throws Exception {
    try {
        // 使用 BatchOperation 进行批量插入
        BatchOperation batch = client.batchOperation("test");

        // 添加多个插入操作
        // 注意需要通过 setPartitionKey 设定分区键 c1 的值
        // 也需要通过 addMutateColVal 设定 c1 的值
        for (int i = 1; i <= 3; i++) {
            Insert insert = new Insert();
            insert.setPartitionKey(row(colVal("c1", (long)(1000 + i))))
                .addMutateColVal(colVal("c1", (long)(1000 + i)), colVal("c2", "batch_test" + i), colVal("c3", (long)(3000 + i)));
            batch.addOperation(insert);
        }

        batch.execute();
        System.out.println("Batch insert successful: 3 operations executed");
    } finally {
        // 清理数据
        truncateTable();
    }
}

```

#### batchInsertOrUpdate

    索引组织表   堆组织表

```java
private static void batchInsertOrUpdateRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey1 = row().add(colVal("employeeId", 1001));
    Row rowKey2 = row().add(colVal("employeeId", 1002));
    Row properties1 = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 10));
    Row properties2 = row().add(colVal("name", "lisi"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 5));
    InsertOrUpdate insertUpOp1 = insertOrUpdate().setRowKey(rowKey1).addMutateRow(properties1);
    InsertOrUpdate insertUpOp2 = insertOrUpdate().setRowKey(rowKey2).addMutateRow(properties2);
    BatchOperationResult res = obkvHandle.batchOperation("employees")
            .addOperation(insertUpOp1,insertUpOp2)
            .execute();
    System.out.println(res.hasError());
}

```

本示例展示了如何使用 `batchInsertOrUpdate` 接口对堆表进行批量写入或更新。请注意，堆表写入操作必须通过 `setPartitionKey` 接口设置分区键的值，以确保数据正确路由。

```java
@Test
public void testBatchInsertOrUpdate1() throws Exception {
    try {
        // 使用 BatchOperation 进行批量插入
        BatchOperation batch = client.batchOperation(tableName);

        // 添加多个插入操作
        // 注意需要通过 setPartitionKey 设定分区键 c1 的值
        // 也需要通过 addMutateColVal 设定 c1 的值
        for (int i = 1; i <= 3; i++) {
            InsertOrUpdate insertOrUpdate = new InsertOrUpdate();
            insertOrUpdate.setPartitionKey(row(colVal("c1", (long)(1000 + i))))
                .addMutateColVal(colVal("c1", (long)(1000 + i)), colVal("c2", "batch_test" + i), colVal("c3", (long)(3000 + i)));
            batch.addOperation(insertOrUpdate);
        }

        batch.execute();
        System.out.println("Batch insertOrUpdate successful: 3 operations executed");
    } finally {
        // 清理数据
        truncateTable();
    }
}

```

#### batchReplace

    索引组织表   堆组织表

```java
private static void batchReplaceRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey1 = row().add(colVal("employeeId", 1001));
    Row rowKey2 = row().add(colVal("employeeId", 1002));
    Row properties1 = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 10));
    Row properties2 = row().add(colVal("name", "lisi"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 5));
    Replace replaceOp1 = replace().setRowKey(rowKey1).addMutateRow(properties1);
    Replace replaceOp2 = replace().setRowKey(rowKey2).addMutateRow(properties2);
    BatchOperationResult res = obkvHandle.batchOperation("employees")
            .addOperation(replaceOp1,replaceOp2)
            .execute();
    System.out.println(res.hasError());
}

```

本示例展示了如何使用 `batchReplace` 接口对堆表进行批量替换。请注意，堆表替换操作必须通过 `setPartitionKey` 接口设置分区键的值，以确保数据正确路由。

```java
@Test
public void testBatchReplace1() throws Exception {
    try {
        // 使用 BatchOperation 进行批量插入
        BatchOperation batch = client.batchOperation(tableName);

        // 添加多个 replace 操作
        // 注意需要通过 setPartitionKey 设定分区键 c1 的值
        // 也需要通过 addMutateColVal 设定 c1 的值
        for (int i = 1; i <= 3; i++) {
            Replace replace = new Replace();
            replace..setPartitionKey(row(colVal("c1", (long)(1000 + i))))
                .addMutateColVal(colVal("c1", (long)(1000 + i)), colVal("c2", "batch_test" + i), colVal("c3", (long)(3000 + i)));
            batch.addOperation(replace);
        }

        batch.execute();
        System.out.println("Batch replace successful: 3 operations executed");
    } finally {
        // 清理数据
        truncateTable();
    }
}

```

#### batchPut

示例代码在一批里写入了 2 行数据，主键 `employeeId` 分别为 `1001` 和 `1002`，每一行都写入了表中全部的 5 个属性列。

```java
private static void batchPutRow(ObTableClient obkvHandle) throws Exception {
    Row rowKey1 = row().add(colVal("employeeId", 1001));
    Row rowKey2 = row().add(colVal("employeeId", 1002));
    Row properties1 = row().add(colVal("name", "zhangsan"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 1))
            .add(colVal("comment", "new employee"));
    Row properties2 = row().add(colVal("name", "lisi"))
            .add(colVal("department", "R&D"))
            .add(colVal("position", "dev"))
            .add(colVal("workYear", 1))
            .add(colVal("comment", "new employee"));
    Put putOp1 = put().setRowKey(rowKey1).addMutateRow(properties1);
    Put putOp2 = put().setRowKey(rowKey2).addMutateRow(properties2);
    BatchOperationResult res = obkvHandle.batchOperation("employees")
            .addOperation(putOp1,putOp2)
            .execute();
    System.out.println(res.hasError());
}

```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
