相关博文原文地址:

博客园:美码师:HBase(2) Java 操作 HBase 教程



一、简介

HBase 本身就是用 Java 编写的,天生自带了 Java 原生API。 我们可以通过 hbase-client 来实现 HBase 数据库的操作。

所以,这次主要介绍该组件的基本用法。

在使用 hbase-client 之前,有几个要点需要注意:

  • 客户端需要能访问 Zoopkeeper,再获得 HMaster、RegionServer 实例进行操作
  • 客户端需运行在HBase/Hadoop 集群内,HBase会使用 hostname 来定位节点,因此要求客户端能访问到对应的主机名(或子域名)

    如果是远程客户端则需要配置本地的hosts文件。

下面这个图,有助于理解 Client 与 HBase 集群的交互架构:

二、hbase-client 引入

在 Maven 的 pom.xml 中添加依赖:

<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.5</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>2.1.5</version>
</dependency>

客户端版本和 HBase 版本需要保持一致,否则可能会遇到不兼容的问题。

三、连接操作

/**
* 建立连接
*
* @return
*/
public static Connection getConnection() {
try {
//获取配置
Configuration configuration = getConfiguration();
//检查配置
HBaseAdmin.checkHBaseAvailable(configuration);
return ConnectionFactory.createConnection(configuration);
} catch (IOException | ServiceException e) {
throw new RuntimeException(e);
}
} /**
* 获取配置
*
* @return
*/
private static Configuration getConfiguration() {
try {
Properties props = PropertiesLoaderUtils.loadAllProperties("hbase.properties");
String clientPort = props.getProperty("hbase.zookeeper.property.clientPort");
String quorum = props.getProperty("hbase.zookeeper.quorum"); logger.info("connect to zookeeper {}:{}", quorum, clientPort); Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.property.clientPort", clientPort);
config.set("hbase.zookeeper.quorum", quorum);
return config;
} catch (IOException e) {
throw new RuntimeException(e);
}
}

四、表操作

增删改查方法封装如下:

/**
* 创建表
* @param connection
* @param tableName
* @param columnFamilies
* @throws IOException
*/
public static void createTable(Connection connection, TableName tableName, String... columnFamilies) throws IOException {
Admin admin = null;
try {
admin = connection.getAdmin();
if (admin.tableExists(tableName)) {
logger.warn("table:{} exists!", tableName.getName());
} else {
TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName);
for (String columnFamily : columnFamilies) {
builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(columnFamily));
}
admin.createTable(builder.build());
logger.info("create table:{} success!", tableName.getName());
}
} finally {
if (admin != null) {
admin.close();
}
}
} /**
* 插入数据
*
* @param connection
* @param tableName
* @param rowKey
* @param columnFamily
* @param column
* @param data
* @throws IOException
*/
public static void put(Connection connection, TableName tableName,
String rowKey, String columnFamily, String column, String data) throws IOException { Table table = null;
try {
table = connection.getTable(tableName);
Put put = new Put(Bytes.toBytes(rowKey));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column), Bytes.toBytes(data));
table.put(put);
} finally {
if (table != null) {
table.close();
}
}
} /**
* 根据row key、column 读取
*
* @param connection
* @param tableName
* @param rowKey
* @param columnFamily
* @param column
* @throws IOException
*/
public static String getCell(Connection connection, TableName tableName, String rowKey, String columnFamily, String column) throws IOException {
Table table = null;
try {
table = connection.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column)); Result result = table.get(get);
List<Cell> cells = result.listCells(); if (CollectionUtils.isEmpty(cells)) {
return null;
}
String value = new String(CellUtil.cloneValue(cells.get(0)), "UTF-8");
return value;
} finally {
if (table != null) {
table.close();
}
}
} /**
* 根据rowkey 获取一行
*
* @param connection
* @param tableName
* @param rowKey
* @return
* @throws IOException
*/
public static Map<String, String> getRow(Connection connection, TableName tableName, String rowKey) throws IOException {
Table table = null;
try {
table = connection.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey)); Result result = table.get(get);
List<Cell> cells = result.listCells(); if (CollectionUtils.isEmpty(cells)) {
return Collections.emptyMap();
}
Map<String, String> objectMap = new HashMap<>();
for (Cell cell : cells) {
String qualifier = new String(CellUtil.cloneQualifier(cell));
String value = new String(CellUtil.cloneValue(cell), "UTF-8");
objectMap.put(qualifier, value);
}
return objectMap;
} finally {
if (table != null) {
table.close();
}
}
} /**
* 扫描权标的内容
*
* @param connection
* @param tableName
* @param rowkeyStart
* @param rowkeyEnd
* @throws IOException
*/
public static List<Map<String, String>> scan(Connection connection, TableName tableName, String rowkeyStart, String rowkeyEnd) throws IOException {
Table table = null;
try {
table = connection.getTable(tableName);
ResultScanner rs = null;
try {
Scan scan = new Scan();
if (!StringUtils.isEmpty(rowkeyStart)) {
scan.withStartRow(Bytes.toBytes(rowkeyStart));
}
if (!StringUtils.isEmpty(rowkeyEnd)) {
scan.withStopRow(Bytes.toBytes(rowkeyEnd));
}
rs = table.getScanner(scan); List<Map<String, String>> dataList = new ArrayList<>();
for (Result r : rs) {
Map<String, String> objectMap = new HashMap<>();
for (Cell cell : r.listCells()) {
String qualifier = new String(CellUtil.cloneQualifier(cell));
String value = new String(CellUtil.cloneValue(cell), "UTF-8");
objectMap.put(qualifier, value);
}
dataList.add(objectMap);
}
return dataList;
} finally {
if (rs != null) {
rs.close();
}
}
} finally {
if (table != null) {
table.close();
}
}
} /**
* 删除表
*
* @param connection
* @param tableName
* @throws IOException
*/
public static void deleteTable(Connection connection, TableName tableName) throws IOException {
Admin admin = null;
try {
admin = connection.getAdmin();
if (admin.tableExists(tableName)) {
//现执行disable
admin.disableTable(tableName);
admin.deleteTable(tableName);
}
} finally {
if (admin != null) {
admin.close();
}
}
}

五、运行测试

  1. 建立 DeviceState 表;
  2. 定义 name/state 两个列簇;
  3. 写入列数据;
  4. 读取列、行,范围读取;
  5. 删除操作
private static final Logger logger = LoggerFactory.getLogger(HBaseTest.class);

public static void main(String[] args) {

    Connection connection = null;
try {
connection = getConnection();
TableName tableName = TableName.valueOf("DeviceState"); //创建DeviceState表
createTable(connection, tableName, "name", "state"); logger.info("创建表 {}", tableName.getNameAsString()); //写入数据
put(connection, tableName, "row1", "name", "c1", "空调");
put(connection, tableName, "row1", "state", "c2", "打开");
put(connection, tableName, "row2", "name", "c1", "电视机");
put(connection, tableName, "row2", "state", "c2", "关闭"); logger.info("写入数据."); String value = getCell(connection, tableName, "row1", "state", "c2");
logger.info("读取单元格-row1.state:{}", value); Map<String, String> row = getRow(connection, tableName, "row2");
logger.info("读取单元格-row2:{}", JsonUtil.toJson(row)); List<Map<String, String>> dataList = scan(connection, tableName, null, null);
logger.info("扫描表结果-:\n{}", JsonUtil.toPrettyJson(dataList)); //删除DeviceState表
deleteTable(connection, tableName);
logger.info("删除表 {}", tableName.getNameAsString()); logger.info("操作完成.");
} catch (Exception e) {
logger.error("操作出错", e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (IOException e) {
logger.error("error occurs", e);
}
}
} }

执行代码,控制台输出如下:

INFO -createTable(HBaseTest.java:89) - create table:[68, 101, 118, 105, 99, 101, 83, 116, 97, 116, 101] success!
INFO -main(HBaseTest.java:32) - 创建表 DeviceState
INFO -main(HBaseTest.java:40) - 写入数据.
INFO -main(HBaseTest.java:43) - 读取单元格-row1.state:打开
INFO -main(HBaseTest.java:46) - 读取单元格-row2:{"c1":"电视机","c2":"关闭"}
INFO -main(HBaseTest.java:49) - 扫描表结果-:
[ {
"c1" : "空调",
"c2" : "打开"
}, {
"c1" : "电视机",
"c2" : "关闭"
} ]
INFO -HBaseAdmin$9.call(HBaseAdmin.java:1380) - Started disable of DeviceState
INFO -HBaseAdmin$DisableTableFuture.postOperationResult(HBaseAdmin.java:1409) - Disabled DeviceState
INFO -HBaseAdmin$DeleteTableFuture.postOperationResult(HBaseAdmin.java:965) - Deleted DeviceState
INFO -main(HBaseTest.java:53) - 删除表 DeviceState
INFO -main(HBaseTest.java:55) - 操作完成.

Java 操作 HBase 教程的更多相关文章

  1. HBase(2) Java 操作 HBase 教程

    目录 一.简介 二.hbase-client 引入 三.连接操作 四.表操作 五.运行测试 FAQ 参考文档 一.简介 在上一篇文章 HBase 基础入门 中,我们已经介绍了 HBase 的一些基本概 ...

  2. Hbase深入学习(六) Java操作HBase

    Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...

  3. Java操作hbase总结

    用过以后,总得写个总结,不然,就忘喽. 一.寻找操作的jar包. java操作hbase,首先要考虑到使用hbase的jar包. 因为咱装的是CDH5,比较方便,使用SecureCRT工具,远程连接到 ...

  4. java操作Hbase实例

    所用HBase版本为1.1.2,hadoop版本为2.4 /* * 创建一个students表,并进行相关操作 */ import java.io.IOException; import java.u ...

  5. 错误: 找不到或无法加载主类 java操作hbase出错

    用java操作hbase 利用maven引入hbase包后发现无法启动程序,然后网上说是包的冲突. 我引入了下面三个包然后程序就不能运行了. <dependency> <groupI ...

  6. 【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  7. (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  8. Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  9. HBase篇--HBase操作Api和Java操作Hbase相关Api

    一.前述. Hbase shell启动命令窗口,然后再Hbase shell中对应的api命令如下. 二.说明 Hbase shell中删除键是空格+Ctrl键. 三.代码 1.封装所有的API pa ...

随机推荐

  1. 深入理解Redis系列之持久化

    redis持久化配置 redis.conf // RDB配置 save 900 1 save 300 10 save 60 10000 // AOF配置 appendonly yes //AOF三种同 ...

  2. maven中pom的结构介绍

    1.自己的坐标 groupId-->artifactId-->version> ` 2.打包方式 jar war pom packaging-->jar/war/pom 3. ...

  3. volatile 关键字精讲

    1.错误案例 通过一个案例引出volatile关键字,例如以下代码示例 : 此时没有加volatile关键字两个线程间的通讯就会有问题 public class ThreadsShare { priv ...

  4. try catch finally语句块中存在return语句时的执行情况剖析

    2种场景 (1) try中有return,finally中没有return(注意会改变返回值的情形);(2) try中有return,finally中有return; 场景代码分析(idea亲测) 场 ...

  5. 【模拟】P1143进制转换

    题目相关 题目描述 请你编一程序实现两种不同进制之间的数据转换. 输入格式 共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A- ...

  6. 直播预告:Quadro RTX显卡助力Twinmotion在建筑表现领域火力全开

    新年伊始,泛CG继续起航! 2021年首期泛CG分享会 我们邀请了两位业界大咖一起分享 NVIDIA GPU实时渲染在建筑可视化领域的应用 新的一年,继续相约! 1.嘉宾介绍 魏老师从事设计可视化工作 ...

  7. [C#.NET 拾遗补漏]14:使用结构体实现共用体

    在 C 和 C# 编程语言中,结构体(Struct)是值类型数据结构,它使得一个单一变量可以存储多种类型的相关数据.在 C 语言中还有一种和结构体非常类似的语法,叫共用体(Union),有时也被直译为 ...

  8. 借助Docker搭建JMeter+Grafana+Influxdb监控平台

    我们都知道Jmeter提供了原生的结果查看,既然有原生的查看结果,为什么还要多此一举使用其他工具进行查看呢,除了查看内容丰富外还有最主要的原因:Jmeter提供的查看结果插件本身是比较消耗性能的,所以 ...

  9. (十三)利用BASE_DIR来import模板

    实际工程的组织架构一般是这样的: bin包下的bin.py是实际的执行文件,my_mould包下的是业务逻辑的实现模板 bin.py需要import my_mould下的py文件,而bin和my_mo ...

  10. 怎么判断是旧版本的ext3还是新版本?

    怎么判断是旧版本的ext3还是新版本的?   ---高性能419