0%

HBase客户端API

HBase客户端API实战指南:从基础操作到高级功能

HBase 提供了丰富的 Java 客户端 API,用于实现数据的增删改查、过滤器查询和计数器等功能。本文基于实战场景,详细讲解 HBase 客户端 API 的核心用法,包括连接管理、数据操作、过滤器使用及计数器功能,帮助开发者快速上手。

环境准备与连接管理

在使用 HBase API 前,需确保项目引入 HBase 依赖(以 Maven 为例),并正确配置 HBase 连接信息(hbase-site.xml 需放在项目 classpath 下)。

依赖引入

1
2
3
4
5
<dependency>  
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.2.7</version> <!-- 与 HBase 集群版本一致 -->
</dependency>

连接初始化

HBase 客户端通过 Connection 对象管理与集群的连接,Admin 用于 DDL 操作,Table 用于 DML 操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import org.apache.hadoop.hbase.client.Admin;  
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.TableName;

public class HBaseClient {
// 全局连接对象(线程安全,推荐单例)
private static Connection conn;
// DDL 操作对象
private static Admin admin;
// DML 操作对象(针对 test 表)
private static Table table;

static {
try {
// 从配置文件加载连接信息(hbase-site.xml)
conn = ConnectionFactory.createConnection();
admin = conn.getAdmin();
// 指定操作的表名(需提前创建)
table = conn.getTable(TableName.valueOf("test"));
} catch (IOException e) {
e.printStackTrace();
}
}
}

核心数据操作 API

插入数据(Put)

使用 Put 类向表中插入或更新数据,需指定 RowKey、列族、列名和值(均为字节数组)。

方法实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**  
* 插入或更新数据
* @param rowKey 行键
* @param family 列族
* @param qualifier 列名
* @param value 数据值
*/
public static void testPut(String rowKey, String family, String qualifier, String value) throws IOException {
// 创建 Put 对象,指定 RowKey
Put put = new Put(Bytes.toBytes(rowKey));
// 添加列数据:列族、列名、值(均需转为字节数组)
put.addColumn(
Bytes.toBytes(family),
Bytes.toBytes(qualifier),
Bytes.toBytes(value)
);
// 执行插入
table.put(put);
System.out.println("数据插入成功");
}
调用示例
1
testPut("123456", "info", "name", "zs");  // 向 test 表插入 RowKey=123456,info:name=zs  

查询数据(Get)

使用 Get 类查询单行数据,支持指定列族或列名,减少无效数据传输。

方法实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**  
* 查询单行数据
* @param rowKey 行键
* @param family 列族
* @param qualifier 列名
*/
public static void testGet(String rowKey, String family, String qualifier) throws IOException {
// 创建 Get 对象,指定 RowKey
Get get = new Get(Bytes.toBytes(rowKey));
// 指定查询的列(可选,不指定则返回整行)
get.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));
// 执行查询
Result result = table.get(get);
// 解析结果(获取指定列的值)
byte[] valueBytes = result.getValue(Bytes.toBytes(family), Bytes.toBytes(qualifier));
if (valueBytes != null) {
System.out.println("查询结果:" + Bytes.toString(valueBytes)); // 输出:zs
}
}
调用示例
1
testGet("123456", "info", "name");  // 查询 RowKey=123456 的 info:name 列  

删除数据(Delete)

使用 Delete 类删除指定行或列,支持删除单行、单列或多列。

方法实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**  
* 删除指定列数据
* @param rowKey 行键
* @param family 列族
* @param qualifier 列名
*/
public static void testDelete(String rowKey, String family, String qualifier) throws IOException {
// 创建 Delete 对象,指定 RowKey
Delete delete = new Delete(Bytes.toBytes(rowKey));
// 指定删除的列(可选,不指定则删除整行)
delete.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));
// 执行删除
table.delete(delete);
System.out.println("数据删除成功");
}
调用示例
1
testDelete("123456", "info", "name");  // 删除 RowKey=123456 的 info:name 列  

批量扫描(Scan)

使用 Scan 类批量查询数据,支持范围扫描、列过滤和分页,适合全表或大范围数据查询。

方法实现(带过滤器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**  
* 带过滤器的批量扫描
* @param family 列族
* @param qualifier 列名
*/
public static void testScanWithFilter(String family, String qualifier) throws IOException {
// 创建 Scan 对象,可指定 RowKey 范围(startRow/stopRow)
Scan scan = new Scan();
// 指定查询的列族和列
scan.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));
// 添加分页过滤器:只返回 1 行数据
Filter pageFilter = new PageFilter(1);
scan.setFilter(pageFilter);

// 执行扫描,获取结果迭代器
ResultScanner scanner = table.getScanner(scan);
// 遍历结果
for (Result result : scanner) {
byte[] rowKey = result.getRow(); // 获取当前行的 RowKey
byte[] valueBytes = result.getValue(Bytes.toBytes(family), Bytes.toBytes(qualifier));
System.out.println("RowKey: " + Bytes.toString(rowKey) + ", Value: " + Bytes.toString(valueBytes));
}
// 关闭扫描器(释放资源)
scanner.close();
}
调用示例
1
testScanWithFilter("info", "name");  // 扫描 info:name 列,只返回 1 行  

计数器(Increment)

HBase 提供原子性计数器功能,通过 incrementColumnValue 实现累加,适合统计曝光量、点击量等场景。

方法实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**  
* 计数器自增与查询
* @param rowKey 行键
* @param family 列族
* @param qualifier 列名
*/
public static void testIncr(String rowKey, String family, String qualifier) throws IOException {
// 自增 1(返回值为自增后的值)
long newValue = table.incrementColumnValue(
Bytes.toBytes(rowKey),
Bytes.toBytes(family),
Bytes.toBytes(qualifier),
1 // 步长,可正可负
);
System.out.println("自增后的值:" + newValue);

// 查询当前值(步长为 0,不改变计数器)
long currentValue = table.incrementColumnValue(
Bytes.toBytes(rowKey),
Bytes.toBytes(family),
Bytes.toBytes(qualifier),
0
);
System.out.println("当前值:" + currentValue);
}
调用示例
1
testIncr("did222", "camp", "501");  // 对 did222:camp:501 计数器自增 1  

API 核心类与注意事项

1. 核心类作用

类名 作用
Connection 管理 HBase 集群连接,线程安全,推荐单例复用
Admin 用于表的创建、删除、启用 / 禁用等 DDL 操作
Table 用于数据的插入、查询、删除等 DML 操作,非线程安全,建议用完即关
Put/Get/Delete/Scan 分别对应插入、查询、删除、扫描操作的参数封装类
Filter 扫描过滤器,如 PageFilter(分页)、RowFilter(行键过滤)等

2. 注意事项

  • 资源释放TableResultScanner 等对象需手动关闭(或用 try-with-resources),避免连接泄漏。
  • 字节数组转换:HBase 内部数据均为字节数组,需使用 Bytes.toBytes()Bytes.toString() 转换。
  • 线程安全ConnectionAdmin 线程安全,Table 非线程安全,多线程需单独创建。
  • 异常处理:所有 API 可能抛出 IOException,需捕获或向上传递。

完整示例代码结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import org.apache.hadoop.hbase.client.*;  
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.filter.Filter;

import java.io.IOException;

public class HBaseClient {
private static Connection conn;
private static Admin admin;
private static Table table;

static {
try {
conn = ConnectionFactory.createConnection();
admin = conn.getAdmin();
table = conn.getTable(TableName.valueOf("test"));
} catch (IOException e) {
e.printStackTrace();
}
}

// 插入数据
public static void testPut(...) throws IOException { ... }

// 查询数据
public static void testGet(...) throws IOException { ... }

// 删除数据
public static void testDelete(...) throws IOException { ... }

// 带过滤器扫描
public static void testScanWithFilter(...) throws IOException { ... }

// 计数器
public static void testIncr(...) throws IOException { ... }

// 主方法测试
public static void main(String[] args) throws IOException {
testPut("123456", "info", "name", "zs");
testGet("123456", "info", "name");
testScanWithFilter("info", "name");
testIncr("did222", "camp", "501");
testDelete("123456", "info", "name");

// 关闭资源
table.close();
admin.close();
conn.close();
}
}

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10