HBase的Java API的操作
准备工作
- 1- 创建一个新的工程
- 2- 导入相关的依赖
<repositories><!--代码库-->
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<!--HBASE 核心客户端包-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
</configuration>
</plugin>
</plugins>
</build>
- 3- 创建包结构: com.itheima.hbase
- 4- 在此包下, 创建一个测试类: HBaseTest
package com.itheima.hbase;
public class HBaseTest {
}
创建表
需求说明:
将水表抄表数据存储到HBase
- 操作步骤:
1- 创建Java连接HBase的连接对象
2- 根据连接对象, 获取相关的管理对象: Admin(表定义语句操作) Table(表数据操作)
3- 执行相关的操作
4- 处理结果集(只有查询才需要处理结果集)
5- 释放资源
代码实现:
package com.itheima.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.junit.Test;
public class HBaseTest {
// 创建表
@Test
public void test01_createTable() throws Exception{
// 1- 创建Java连接HBase的连接对象
// Configuration conf = new Configuration();
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum","node1:2181,node2:2181,node3:2181");
Connection hbaseConn = ConnectionFactory.createConnection(conf);
// 2- 根据连接对象, 获取相关的管理对象: Admin(表定义语句操作) Table(表数据操作)
Admin admin = hbaseConn.getAdmin();
// 3- 执行相关的操作
boolean flag = admin.tableExists(TableName.valueOf("WATER_BILL")); // 存在 返回True 不存在 返回False
if(!flag){
// 说明表不存在
// ColumnFamilyDescriptor : 列族的结构信息对象
ColumnFamilyDescriptor familyDesc = ColumnFamilyDescriptorBuilder.newBuilder("C1".getBytes()).build();
// TableDescriptor : 表的结构信息对象
TableDescriptor desc = TableDescriptorBuilder
.newBuilder(TableName.valueOf("WATER_BILL"))
.setColumnFamily(familyDesc).build();
admin.createTable(desc);
}
// 4- 处理结果集(只有查询才需要处理结果集)
// 5- 释放资源
admin.close();
hbaseConn.close();
}
}
插入数据
代码实现:
// 插入数据
@Test
public void test02_addData() throws Exception{
//1. 根据HBase的连接工厂, 创建HBase的连接对象
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum","node1:2181,node2:2181,node3:2181");
Connection hbaseConn = ConnectionFactory.createConnection(conf);
//2. 根据连接对象, 获取相关的管理对象: Admin Table
Table table = hbaseConn.getTable(TableName.valueOf("WATER_BILL"));
//3. 执行相关的操作: 添加数据 put '表名', 'rk','列名','列值'
Put put = new Put("4944191".getBytes());
put.addColumn("C1".getBytes(),"name".getBytes(),"登卫红".getBytes());
put.addColumn("C1".getBytes(),"address".getBytes(),"贵州省铜仁市德江县7单元267室".getBytes());
put.addColumn("C1".getBytes(),"sex".getBytes(),"男".getBytes());
table.put(put);
//4. 处理结果集
//5. 释放资源
table.close();
hbaseConn.close();
}
提取公共的方法
// 会在 @Test方法执行前 执行
private Connection hbaseConn;
private Admin admin;
private Table table;
private String tableName = "WATER_BILL";
@Before
public void before() throws Exception{
//1. 根据HBase的连接工厂, 创建HBase的连接对象
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum","node1:2181,node2:2181,node3:2181");
hbaseConn = ConnectionFactory.createConnection(conf);
//2. 根据连接对象, 获取相关的管理对象: Admin Table
admin = hbaseConn.getAdmin();
table = hbaseConn.getTable(TableName.valueOf(tableName));
}
// 会在@Test方法执行后 执行
@After
public void after() throws Exception{
//5. 释放资源
admin.close();
table.close();
hbaseConn.close();
}
查询某一条数据
// 根据rowkey 查询数据
@Test
public void test03_findByRowKey() throws Exception{
//3. 执行相关的操作: rowkey查询 get '表名','rk'
Get get = new Get("4944191".getBytes());
// get.addColumn("C1".getBytes(),"name".getBytes());
// get.addColumn("C1".getBytes(),"sex".getBytes());
// get.addFamily("C1".getBytes());
Result result = table.get(get); // 一个result 表示就是一行数据, 而一行数据是由多个单元格构成的
//4. 处理结果集
// 4.1 从result中拿到每一个单元格
List<Cell> cells = result.listCells();
// 4.2 遍历每一个单元格
for (Cell cell : cells) {
// 4.3 从单元格中获取数据
// byte[] familyArray = cell.getFamilyArray();
// String family = new String(familyArray, cell.getFamilyOffset(), cell.getFamilyLength());
// System.out.println(family);
// 获取rowkey
String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
// 获取 列族
String family = Bytes.toString(CellUtil.cloneFamily(cell));
// 获取 列名
String columnName = Bytes.toString(CellUtil.cloneQualifier(cell));
// 获取列值
String columnValue = Bytes.toString(CellUtil.cloneValue(cell));
System.out.println("rowkey为:"+rowkey +"; 列族为:"+family +"; 列名为:"+columnName+";列值为:"+columnValue);
}
}
如何删除某一条数据
// 删除数据
@Test
public void test04_deleteData() throws Exception{
//3. 执行相关的操作
Delete delete = new Delete("4944191".getBytes()); // 直接删除一整行数据的
// delete.addFamily("C1".getBytes()); 支持删除某一列族下的数据
// delete.addColumn("C1".getBytes(),"name".getBytes()); 支持删除某一列的数据
table.delete(delete);
}
如何删除表
// 删除表
@Test
public void test05_deleteTable() throws Exception{
//3. 执行相关的操作: 删除表
// 3.1 判断表是否是禁用状态
boolean flag = admin.isTableDisabled(TableName.valueOf(tableName)); // 禁用 为True
if (!flag){
// 表示表没有被禁用, 首先要先禁用表
admin.disableTable(TableName.valueOf(tableName));
}
admin.deleteTable(TableName.valueOf(tableName));
}
导入数据操作
- 导入数据语法
hbase org.apache.hadoop.hbase.mapreduce.Import 表名 HDFS数据文件路径
注意: 此命令需要在linux的命令窗口下执行(而非Hbase的shell窗口下)
- 导出数据语法
hbase org.apache.hadoop.hbase.mapreduce.Export 表名 导出路径
注意: 此命令需要在linux的命令窗口下执行(而非Hbase的shell窗口下)
完成10W抄表数据导入操作:
1- 将资料中 10w的抄表数据上传到Linux
2- 在linux中将文件上传到HDFS中:
hdfs dfs -mkdir -p /hbase/water_bill/input
hdfs dfs -put part-m-00000_10w /hbase/water_bill/input
3- 执行导入数据操作
hbase org.apache.hadoop.hbase.mapreduce.Import WATER_BILL /hbase/water_bill/input/part-m-00000_10w
基于SCAN扫描数据
需求: 查询 2020年 6月份的所有用户的用水量 :
日期字段: C1: RECORD_DATE (String)
用水量字段: C1:NUM_USAGE (Double)
用户字段: C1:NAME(String)
/*
需求: 查询 2020年 6月份的所有用户的用水量 :
日期字段: C1: RECORD_DATE (String)
用水量字段: C1:NUM_USAGE (Double)
用户字段: C1:NAME(String)
SQL: select 用户, 日期, 用水量 from water_bill where RECORD_DATE >= '2020-06-01' and RECORD_DATE < '2020-07-01'
*/
@Test
public void test06_findScan() throws Exception{
//3- 执行相关的操作
Scan scan = new Scan();
// 3.1 设置过滤器
SingleColumnValueFilter filter1 = new SingleColumnValueFilter(
"C1".getBytes(),"RECORD_DATE".getBytes(), CompareOperator.GREATER_OR_EQUAL,new BinaryComparator("2020-06-01".getBytes()));
SingleColumnValueFilter filter2 = new SingleColumnValueFilter(
"C1".getBytes(),"RECORD_DATE".getBytes(), CompareOperator.LESS,new BinaryComparator("2020-07-01".getBytes()));
// 将过滤器组合在一起, 默认的关系为并列
FilterList filterList = new FilterList();
filterList.addFilter(filter1);
filterList.addFilter(filter2);
//3.2 限制返回来的字段
scan.addColumn("C1".getBytes(),"NAME".getBytes());
scan.addColumn("C1".getBytes(),"RECORD_DATE".getBytes());
scan.addColumn("C1".getBytes(),"NUM_USAGE".getBytes());
// 3.3 限制返回来的条数
scan.setLimit(10);
// 3.4 根据rowkey的范围获取数据
// scan.withStartRow("开始rowkey".getBytes());
// scan.withStopRow("结束rowkey".getBytes());
scan.setFilter(filterList);
ResultScanner results = table.getScanner(scan);
//4. 处理结果集
// 4.1 遍历results 获取每一行的result对象
for (Result result : results) {
// 4.2 获取每一行的所有的单元格
List<Cell> cellList = result.listCells();
// 4.3 遍历每一个单元格
for (Cell cell : cellList) {
// 4.4 从单元格中获取数据
// 获取rowkey
String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
// 获取 列族
String family = Bytes.toString(CellUtil.cloneFamily(cell));
// 获取列名
String columnName = Bytes.toString(CellUtil.cloneQualifier(cell));
// 获取 列值
Object columnValue;
if(columnName.equals("NUM_USAGE")){
columnValue = Bytes.toDouble(CellUtil.cloneValue(cell));
}else {
columnValue = Bytes.toString(CellUtil.cloneValue(cell));
}
System.out.println("rowkey:"+ rowkey+";列族:"+family+";列名为:"+columnName+";列值为:"+columnValue);
}
System.out.println("========================");
}
}