---
title: "OBKV-HBase 数据操作示例 - OceanBase 数据库 V4.2.1 | OceanBase 文档中心"
description: OBKV-HBase 数据操作示例 本文以具体的示例为例来介绍如果通过 OBKV-HBase 客户端进行数据处理。 说明 OBKV-HBase 客户端已支持的接口列表，参见 和 HBase 的兼容性 。 准备工作 基于以下示例进行体验之前，请确保您已经完成如下准备工作： 已经部署了 OceanBase 集群。关于支持…
---
切换语言

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

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

# OBKV-HBase 数据操作示例

更新时间：2025-03-20 11:21:26

[编辑](https://github.com/oceanbase/oceanbase-kv/edit/V4.2.1/zh-CN/200.obkv-hbase/200.obkv-hbase-develop/300.obkv-hbase-demo.md)  

本文以具体的示例为例来介绍如果通过 OBKV-HBase 客户端进行数据处理。

#### 说明

OBKV-HBase 客户端已支持的接口列表，参见[和 HBase 的兼容性](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000916164)。

## 准备工作

基于以下示例进行体验之前，请确保您已经完成如下准备工作：

- 已经部署了 OceanBase 集群。关于支持的部署方案、部署方式以及详细的部署操作，参见 [部署简介](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000916166)。
 - 已经创建了 MySQL 租户。关于创建租户的详细操作，参见 [创建租户](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000218355)。
 - 已经创建了数据库。关于创建数据库的详细操作，参见 [创建数据库](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000220194)。
 - 已经创建了 OBKV-HBase 数据表。关于创建 OBKV-HBase 数据表的详细操作，参见 [数据库模式设计](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000916168)。

  在本示例中，表名为 htable1$family。建表示例如下。

  ```
  CREATE TABLEGROUP htable1;

  CREATE TABLE htable1$family (
    K varbinary(1024),
    Q varbinary(256),
    T bigint,
    V varbinary(1048576) NOT NULL,
    PRIMARY KEY(K, Q, T))
    TABLEGROUP =  htable1 ;

  ```
 - 本示例通过 OHTable 连接 OBKV-HBase 集群并进行数据处理，请确保已经完成 OBKV-HBase 客户端的部署和配置，并通过 OHTable 连接了集群。详细操作参见 [使用 OBKV-HBase 客户端连接集群](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000916169)。

## 注意事项

- 代码示例中的执行结果，依赖下面各个操作的顺序，如需复现，请按照顺序执行。
 - 为了比较直观的观察数据库中的结果，示例中采用 MySQL 客户端连接 OBKV-HBase，通过 SQL 来查询数据库表 htable1$family 的状态。

## Put

**函数说明：**

- 插入数据。

**函数原型：**

- void put(Put put)
 - void put(List puts)

**参数列表：**

- put：Put 对象，用于插入单条记录。
 - puts：Put 对象集合，用于批量插入多条记录。

**操作示例：**

```
// 插入单条记录
String key = "testKey0";
String family = "family";
String column = "column";
String value = "putValue";
Put put = new Put(key.getBytes());
put.add(family.getBytes(), column.getBytes(), value.getBytes());
hTable.put(put);

// 插入多条记录
Put put1 = new Put(Bytes.toBytes("testKey1"));
put1.add(toBytes(family), toBytes(column), toBytes(value));
//put1.add(toBytes(family), toBytes(column), System.currentTimeMillis(), toBytes(value));

Put put2 = new Put(Bytes.toBytes("testKey2"));
put2.add(toBytes(family), toBytes(column), toBytes(value));
//put2.add(toBytes(family), toBytes(column), System.currentTimeMillis(), toBytes(value));
List<Put> puts = new ArrayList<Put>();
puts.add(put1);
puts.add(put2);
hTable.put(puts);

```

```
MySQL [test]> select * from htable1$family;
+----------+--------+----------------+----------+
| K        | Q      | T              | V        |
+----------+--------+----------------+----------+
| testKey0 | column | -1715961035391 | putValue |
| testKey1 | column | -1715961035471 | putValue |
| testKey2 | column | -1715961035471 | putValue |
+----------+--------+----------------+----------+

```

**备注：**

- 上述示例中，向数据库中插入了 3 个 Cell。

## Get

**函数说明：**

- 获取指定行的数据。

**函数原型：**

- Result get(final Get get)
 - Result[] get(List gets)

**参数列表：**

- get：Get 对象，需要使用 addColumn 或 addFamily 来指定操作目标。
 - gets：Get 对象列表，保存 Get 对象。

**操作示例：**

```
// 获取 one family
String key = "testKey0";
String family = "family";
int maxVersion = 1;
Get get = new Get(key.getBytes());
get.addFamily(family.getBytes());
get.setMaxVersions(maxVersion);
Result result = hTable.get(get);
if (result.list() != null) {
    System.out.printf("Get Demo: get cnt:%d%n", result.list().size());
}

```

```
String key = "testKey0";
Get get = new Get(key.getBytes());
Result result = hTable.get(get);
if (result.list() != null) {
    System.out.printf("Get Demo: get cnt:%d%n", result.list().size());
}

```

```
MySQL [test]> select * from htable1$family where k = "testKey0";
+----------+--------+----------------+----------+
| K        | Q      | T              | V        |
+----------+--------+----------------+----------+
| testKey0 | column | -1715961561057 | putValue |
+----------+--------+----------------+----------+

```

**备注：**

- 例子中 Get 的语义，在 HBase 的记录没有多版本的时候，等价于上述的 SQL。
 - 承接于 Put 的例子，数据库中有一条主键为 testKey0 的 Cell。

## Scan

**函数说明：**

- 根据指定条件（scan/family/qualifier）对 Table 进行扫描。

**函数原型：**

- ResultScanner getScanner(byte[] family, byte[] qualifier)
 - ResultScanner getScanner(final byte[] family)
 - ResultScanner getScanner(final Scan scan)

**参数列表：**

- family：目标列簇，这里是指需要过滤的列簇。
 - qualifier：目标列名，这里指需要过滤的列名。
 - scan：Scan 对象，使用 addFamily 或 addColumn 等设置操作目标。

**操作示例：**

```
String startKey = "testKey";
String endKey = "testKey9";
String family = "family";
String column = "column";
int maxVersion = 1;
Scan scan = new Scan();
scan.addColumn(family.getBytes(), column.getBytes());
scan.setMaxVersions(maxVersion);
scan.setStartRow(startKey.getBytes());
scan.setStopRow(endKey.getBytes());
ResultScanner scanner = hTable.getScanner(scan);
for (Result r : scanner) {
    for (KeyValue kv : r.list()) {
        System.out.printf("Scan Demo: Rowkey: %s, Column Family: %s, Column Qualifier: %s, Value: %s, Timestamp: %d%n",
                Bytes.toString(r.getRow()),
                Bytes.toString(kv.getFamily()),
                Bytes.toString(kv.getQualifier()),
                Bytes.toString(kv.getValue()),
                kv.getTimestamp());
    }
}

```

返回结果如下：

```
+----------+--------+----------------+----------+
| K        | Q      | T              | V        |
+----------+--------+----------------+----------+
| testKey0 | column | -1715961561057 | putValue |
| testKey1 | column | -1715961561132 | putValue |
| testKey2 | column1 | -1715961561132 | putValue |
| testKey2 | column2 | -1715961561132 | putValue |

```

OBKV-HBase 支持 Reverse Scan 功能，它允许用户以行键（RowKey）逆序（从大到小）扫描表中的数据，这与常规的正序（从小到大）扫描相反。上条示例逆序扫描示例如下：

```
String startKey = "testKey9";
String endKey = "testKey";
String family = "family";
String column = "column";
int maxVersion = 1;
Scan scan = new Scan();
scan.addColumn(family.getBytes(), column.getBytes());
scan.setMaxVersions(maxVersion);
scan.setStartRow(startKey.getBytes());
scan.setStopRow(endKey.getBytes());
// 设置启用 Reverse scan
scan.setReversed(true);
ResultScanner scanner = hTable.getScanner(scan);
for (Result r : scanner) {
    for (KeyValue kv : r.list()) {
        System.out.printf("Scan Demo: Rowkey: %s, Column Family: %s, Column Qualifier: %s, Value: %s, Timestamp: %d%n",
                Bytes.toString(r.getRow()),
                Bytes.toString(kv.getFamily()),
                Bytes.toString(kv.getQualifier()),
                Bytes.toString(kv.getValue()),
                kv.getTimestamp());
    }
}

```

结果如下：

```
+----------+--------+----------------+----------+
| K        | Q      | T              | V        |
+----------+--------+----------------+----------+
| testKey2 | column1 | -1715961561132 | putValue |
| testKey2 | column2 | -1715961561132 | putValue |
| testKey1 | column | -1715961561132 | putValue |
| testKey0 | column | -1715961561057 | putValue |

```

**备注：**

- 例子中 Scan 的语义，在 HBase 的记录没有多版本的时候，等价于上述的 SQL。
 - 注意 HBase 0.94 的 start 和 endkey 是左闭右开，endkey 扫不到。
 - 承接于 Put 的例子，数据库中有 3 条满足条件的 Cell。

## Increment Column Value

**函数说明：**

- 对表中的某行单列数据进行自增，执行成功则返回自增后的值，指定列的 cell 必须是 long 类型（64 字节整型）。

**函数原型：**

- long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount, boolean writeToWAL)

**参数列表：**

- row：行键。
 - family：目标列簇，这里是建表时指定的列簇。
 - qualifier：目标列名。
 - amount：增加的数量（可以为负值）。
 - writeToWAL：是否预写日志，OBKV-HBase 不需要设置。

**操作示例：**

```
// 这里展示的是对单列自增 1
String column = "incrementColumn";
String key = "incrementKey";
String family = "family";
long increment_value = 1L;
long ret = hTable.incrementColumnValue(
        key.getBytes(),
        family.getBytes(),
        column.getBytes(),
        increment_value);
System.out.printf("Increment Column Demo: ret: %b%n", ret);

```

```
MySQL [test]> select *,hex(v) from htable1$family where k = "incrementKey";
+--------------+-----------------+----------------+----------+------------------+
| K            | Q               | T              | V        | hex(v)           |
+--------------+-----------------+----------------+----------+------------------+
| incrementKey | incrementColumn | -1715961669857 |          | 0000000000000001 |
+--------------+-----------------+----------------+----------+------------------+

```

**备注：**

- 如果使用 MySQL 客户端查看 HBase 表，可能会发现对应 Cell 的 V 字段没有值，可以用 hex(v) 来显示。
 - 如上，Increment 的行为是如果数据库中查询不到满足条件的 Cell，那么会生成一个 Cell，值默认为 0，接着进行 Increment。

## Increment

**函数说明：**

- 对指定行中的单列或多列进行增加，指定列的 cell 必须是 long 类型（64 字节整型）。

**函数原型：**

- Result increment(Increment increment)

**参数列表：**

- increment： Increment 类型，需要使用 addColumn 进行属性设置。

**操作示例：**

```
// 这里展示的是对单列自增 1
String column = "incrementColumn";
String key = "incrementKey";
String family = "family";
long increment_value = 1L;
Increment increment = new Increment(key.getBytes());
increment.addColumn(family.getBytes(), column.getBytes(), increment_value);
Result r = hTable.increment(increment);

for (KeyValue kv : r.list()) {
    System.out.printf("Increment Demo: Rowkey: %s, Value:%s%n",
            Bytes.toString(r.getRow()),
            Bytes.toLong(kv.getValue()));
}

```

```
MySQL [test]> select *,hex(v) from htable1$family where k = "incrementKey";
+--------------+-----------------+----------------+----------+------------------+
| K            | Q               | T              | V        | hex(v)           |
+--------------+-----------------+----------------+----------+------------------+
| incrementKey | incrementColumn | -1715961734681 |         | 0000000000000002 |
| incrementKey | incrementColumn | -1715961669857 |         | 0000000000000001 |
+--------------+-----------------+----------------+----------+------------------+

```

**备注：**

- 如上，对一个 Cell 多次做自增，会产生多个版本的 Cell。HBase 中没有 Update 的操作语义，对一个 Cell 的修改会变成多版本，用户可以指定版本来做查询。

## Append

**函数说明：**

- 对指定行中的单列或多列进行增加（针对字符类型，例如 byte，string 等）。

**函数原型：**

- Result append(Append append)

**参数列表：**

- append：Append 类型，需要使用 add 函数进行属性设置。

**操作示例：**

```
String column = "appendColumn";
String key = "appendKey";
String family = "family";
Append append = new Append(key.getBytes());
append.add(family.getBytes(), column.getBytes(), toBytes("_append"));
Result r = hTable.append(append);
for (KeyValue kv : r.list()) {
    System.out.printf("Appand Demo: Rowkey: %s, Append Value:%s%n",
            Bytes.toString(r.getRow()),
            Bytes.toString(kv.getValue()));
}

```

```
MySQL [test]> select * from htable1$family where k = "appendKey";
+-----------+--------------+----------------+---------+
| K         | Q            | T              | V       |
+-----------+--------------+----------------+---------+
| appendKey | appendColumn | -1715961265748 | _append |
+-----------+--------------+----------------+---------+

```

**备注：**

- 如上，Append 的行为是如果数据库中查询不到满足条件的 Cell，那么会插入对应的 Cell，值默认为空串，接着对生成的记录进行 Append 操作。

## Delete

**函数说明：**

- 删除指定的存储单元（cells）或行（rows）。

**函数原型：**

- void delete(Delete delete)
 - void delete(List deletes)

**参数列表：**

- deletes：Delete 对象，这里是指需要执行删除的行，通过 deleteFamily 函数设置。

**操作示例：**

```
// 如下是删除某 key，family，column 对应的行
String key = "testKey1";
String family = "family";
String column = "column";
Delete delete = new Delete(key.getBytes());
delete.deleteColumn(family.getBytes(),column.getBytes());
hTable.delete(delete);

```

```
MySQL [test]> select * from htable1$family;
+--------------+-----------------+----------------+----------+
| K            | Q               | T              | V        |
+--------------+-----------------+----------------+----------+
| appendKey    | appendColumn    | -1715961265748 | _append  |
| incrementKey | incrementColumn | -1715961228139 |          |
| incrementKey | incrementColumn | -1715961188112 |          |
| testKey0     | column          | -1715961035391 | putValue |
| testKey2     | column          | -1715961035471 | putValue |
+--------------+-----------------+----------------+----------+

```

**备注：**

- 查询整张表的状态，发现主键为 testKey1 的 Cell 都被删除了。

## Exists

**函数说明：**

- 判断在 Get 对象中设置的列簇或列是否存在，存在则返回 true，反之返回 false。

**函数原型：**

- boolean exists(Get get)

**参数列表：**

- get：Get 对象，使用 addFamily 或 addColumn 来设置操作目标。

**操作示例：**

```
String key = "testKey2";
String family = "family";
Get get = new Get(key.getBytes());
get.addFamily(family.getBytes());
boolean ret = hTable.exists(get);
System.out.printf("Exist Demo: ret: %b%n", ret);

```

```
MySQL [test]> select * from htable1$family where k = "testKey2";
+----------+--------+----------------+----------+
| K        | Q      | T              | V        |
+----------+--------+----------------+----------+
| testKey2 | column | -1715961561132 | putValue |
+----------+--------+----------------+----------+

```

**备注：**

- Exist 语义等同于 Get。

## Check And Put

**函数说明：**

- 检查并替换指定列数据，如果条件满足并替换成功，返回 true，反之返回 false。

**函数原型：**

- boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put)

**参数列表：**

- row：目标行键。
 - family：目标列簇。
 - qualifier：目标列名。
 - value：目标列值。
 - put：需要替换的列值。

**操作示例：**

```
String key = "testKey2";
String family = "family";
String column = "column";
String value = "putValue";
String new_value = "value_new";
Put put = new Put(key.getBytes());
put.add(family.getBytes(), column.getBytes(), new_value.getBytes());
boolean ret = hTable.checkAndPut(
        key.getBytes(),
        family.getBytes(),
        column.getBytes(),
        value.getBytes(),
        put);
System.out.printf("CheckAndPut Demo: ret: %b%n", ret);

```

```
MySQL [test]> select * from htable1$family where k = "testKey2";
+----------+--------+----------------+-----------+
| K        | Q      | T              | V         |
+----------+--------+----------------+-----------+
| testKey2 | column | -1715961408587 | value_new |
| testKey2 | column | -1715961035471 | putValue  |
+----------+--------+----------------+-----------+

```

**备注：**

- 将满足条件的，主键为 testKey2，值为 putValue 的Cell，做了修改，生成一个值为 value_new 的新版本的 Cell。

## Check And Delete

**函数说明：**

- 匹配删除列，若匹配条件符合并删除成功，返回 true，反之返回 false。

**函数原型：**

- boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value, Delete delete)

**参数列表：**

- row：目标匹配行键。
 - family：目标列簇，这里是建表时指定的列簇。
 - qualifier：目标匹配列名。
 - value：目标匹配列值。
 - delete：预期需要删除的列。

**操作示例：**

```
String key = "testKey2";
String family = "family";
String column = "column";
String value = "value_new";
Delete delete = new Delete(key.getBytes());
delete.deleteColumn(family.getBytes(), column.getBytes());
boolean ret = hTable.checkAndDelete(
        key.getBytes(),
        family.getBytes(),
        column.getBytes(),
        value.getBytes(),
        delete);
System.out.printf("CheckAndDelete Demo: ret: %b%n", ret);

```

```
MySQL [test]> select * from htable1$family where k = "testKey2";
+----------+--------+----------------+----------+
| K        | Q      | T              | V        |
+----------+--------+----------------+----------+
| testKey2 | column | -1715961035471 | putValue |
+----------+--------+----------------+----------+

```

**备注：**

- 将满足条件的，主键为 testKey2，值为 value_new 的 Cell，做了删除，数据库中不存在这个 Cell。

## Get Configuration

**函数说明：**

- 返回操作实例中的 config 句柄，可用于在操作中变更属性。

**函数原型：**

- Configuration getConfiguration()

**参数列表：**

- 无

**操作示例：**

```
hTable.getConfiguration().set("rpc.execute.timeout", "1500");

```

 上一篇 下一篇 ![有帮助](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) 咨询热线
