一、创建maven项目
创建maven项目:db_hbase
二、添加依赖
由于需要操作HBase,所以需要在pom.xml中添加hbase-client依赖
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.2.7</version>
</dependency>
以及日志相关配置
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.10</version>
</dependency>
在resources目录中添加log4j.properties文件,文件内容如下:
log4j.rootLogger=info,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
三、创建包和类
在src/main/java目录中创建package:com.imooc.hbase
创建类:HBaseOp
四、对表中的数据进行增删改查
1、首先需要获取HBase数据库连接
代码如下:
//获取配置
Configuration conf = HBaseConfiguration.create();
//指定HBase使用的zk的地址,多个用逗号隔开
conf.set("hbase.zookeeper.quorum", "bigdata01:2181");
//指定HBase在hdfs上的根目录
conf.set("hbase.rootdir","hdfs://bigdata01:9000/hbase");
//创建HBase连接,负责对HBase中数据的一些增删改查(DML操作)
Connection conn = ConnectionFactory.createConnection(conf);
注意:想要在哪台机器上执行代码操作HBase,一定要在这台机器上配置HBase集群所有节点的主机名和IP的映射关系
因为我们在连接HBase集群的时候在代码中指定的是zookeeper集群的地址信息,通过Zookeeper去查找HBase,HBase会在zookeeper里面存储自己的地址信息,存储的是主机名。
所以一定要在执行HBase代码的机器上配置HBase集群所有节点的主机名和IP的映射关系。
注意:代码在windows中执行的时候会提示缺少winutils.exe
[WARN] - Did not find winutils.exe: java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset.
这个警告信息不影响代码执行,在windows中执行会有这个提示,属于正常,把代码打包提交到集群上执行的时候就不会提示这个了,所以不用处理即可。
2、添加数据
//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回put对象
Put put = new Put(Bytes.toBytes("laowang"));
//向put对象中指定列族、列、值
//put 'student','laowang','info:age','18'
put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("18"));
//put 'student','laowang','info:sex','man'
put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("sex"),Bytes.toBytes("man"));
//put 'student','laowang','level:class','A'
put.addColumn(Bytes.toBytes("level"),Bytes.toBytes("class"),Bytes.toBytes("A"));
//向表中添加数据
table.put(put);
//关闭table连接
table.close();
3、查询数据
//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Get对象
Get get = new Get(Bytes.toBytes("laowang"));
//【可选】可以在这里指定要查询指定Rowkey数据哪些列族中的列
// 如果不指定,默认查询指定Rowkey所有列的内容
//get.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"));
//get.addColumn(Bytes.toBytes("info"),Bytes.toBytes("sex"));
Result result = table.get(get);
//如果不清楚HBase中到底有哪些列族和列,可以使用listCells()获取所有cell(单元格),cell对应的是某一个列的数据
List<Cell> cells = result.listCells();
for (Cell cell: cells) {
//注意:下面获取的信息都是字节类型的,可以通过new String(bytes)转为字符串
//列族
byte[] famaily_bytes = CellUtil.cloneFamily(cell);
//列
byte[] column_bytes = CellUtil.cloneQualifier(cell);
//值
byte[] value_bytes = CellUtil.cloneValue(cell);
System.out.println("列族:"+new String(famaily_bytes)+",列:"+new String(column_bytes)+",值:"+new String(value_bytes));
}
System.out.println("========================================================");
//如果明确知道HBase中有哪些列族和列,可以使用getValue(family, qualifier)直接获取指定列族中指定列的数据
byte[] age_bytes = result.getValue(Bytes.toBytes("info"),Bytes.toBytes("age"));
System.out.println("age列的值:"+new String(age_bytes));
//关闭table连接
table.close();
4、查询多版本数据
//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Get对象
Get get = new Get(Bytes.toBytes("laowang"));
//读取cell中的所有历史版本数据,不设置此配置的时候默认只读取最新版本的数据
//可以通过get.readVersions(2)来指定获取多少个历史版本的数据
get.readAllVersions();
Result result = table.get(get);
//获取指定列族中指定列的所有历史版本数据,前提是要设置get.readAllVersions()或者get.readVersions(2),否则只会获取最新数据
List<Cell> columnCells = result.getColumnCells(Bytes.toBytes("info"), Bytes.toBytes("age"));
for (Cell cell :columnCells) {
byte[] value_bytes = CellUtil.cloneValue(cell);
long timestamp = cell.getTimestamp();
System.out.println("值为:"+new String(value_bytes)+",时间戳:"+timestamp);
}
//关闭table连接
table.close();
5、删除数据
//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Delete对象
Delete delete = new Delete(Bytes.toBytes("laowang"));
//【可选】可以在这里指定要删除指定Rowkey数据哪些列族中的列
//delete.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"));
table.delete(delete);
//关闭table连接
table.close();
6、创建和删除表
想要操作表,也就是执行DDL操作,需要获取管理员权限,通过HBase获取
//获取管理权限,负责对HBase中的表进行操作(DDL操作)
Admin admin = conn.getAdmin();
(1)创建表
//指定列族信息
ColumnFamilyDescriptor familyDesc1 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info"))
//在这里可以给列族设置一些属性
.setMaxVersions(3)//指定最多存储多少个历史版本数据
.build();
ColumnFamilyDescriptor familyDesc2 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("level"))
//在这里可以给列族设置一些属性
.setMaxVersions(2)//指定最多存储多少个历史版本数据
.build();
ArrayList<ColumnFamilyDescriptor> familyList = new ArrayList<ColumnFamilyDescriptor>();
familyList.add(familyDesc1);
familyList.add(familyDesc2);
//获取TableDescriptor对象
TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf("test"))//指定表名
.setColumnFamilies(familyList)//指定列族
.build();
//创建表
admin.createTable(desc);
(2)删除表
//删除表,先禁用表
admin.disableTable(TableName.valueOf("test"));
admin.deleteTable(TableName.valueOf("test"));
五、最后对代码进行抽取,便于查看,完整代码如下
package com.imooc.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 操作HBase
* 表:创建、删除
* 数据:增、删、改、查
*/
public class HBaseOp {
public static void main(String[] args) throws Exception {
//获取HBase数据库连接
Connection conn = getConn();
//添加数据
//put(conn);
//查询数据
get(conn);
/**
* 查询多版本的数据
* 当列的值有多个历史版本的时候
*
* 修改列族info的最大历史版本存储数量
* alter 'student',{NAME=>'info',VERSIONS=>3}
*
* 然后再执行下面命令,向列族info中的age列中添加几次数据,实现多历史版本数据存储
* put 'student','laowang','info:age','19'
* put 'student','laowang','info:age','20'
*
*/
//getMoreVersion(conn);
//修改数据--同添加数据
//删除数据
//delete(conn);
//==============================分割线======================
//获取管理权限,负责对HBase中的表进行操作(DDL操作)
Admin admin = conn.getAdmin();
//创建表
//createTable(admin);
//删除表
//deleteTable(admin);
//关闭admin连接
admin.close();
//关闭连接
conn.close();
}
/**
* 删除表
* @param admin
* @throws IOException
*/
private static void deleteTable(Admin admin) throws IOException {
//删除表,先禁用表
admin.disableTable(TableName.valueOf("test"));
admin.deleteTable(TableName.valueOf("test"));
}
/**
* 创建表
* @param admin
* @throws IOException
*/
private static void createTable(Admin admin) throws IOException {
//指定列族信息
ColumnFamilyDescriptor familyDesc1 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info"))
//在这里可以给列族设置一些属性
.setMaxVersions(3)//指定最多存储多少个历史版本数据
.build();
ColumnFamilyDescriptor familyDesc2 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("level"))
//在这里可以给列族设置一些属性
.setMaxVersions(2)//指定最多存储多少个历史版本数据
.build();
ArrayList<ColumnFamilyDescriptor> familyList = new ArrayList<ColumnFamilyDescriptor>();
familyList.add(familyDesc1);
familyList.add(familyDesc2);
//获取TableDescriptor对象
TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf("test"))//指定表名
.setColumnFamilies(familyList)//指定列族
.build();
//创建表
admin.createTable(desc);
}
/**
* 删除数据
* @param conn
* @throws IOException
*/
private static void delete(Connection conn) throws IOException {
//获取Table,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Delete对象
Delete delete = new Delete(Bytes.toBytes("laowang"));
//【可选】可以在这里指定要删除指定Rowkey数据哪些列族中的列
//delete.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"));
table.delete(delete);
//关闭table连接
table.close();
}
/**
* 查询多版本的数据
* @param conn
* @throws IOException
*/
private static void getMoreVersion(Connection conn) throws IOException {
//获取Table,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Get对象
Get get = new Get(Bytes.toBytes("laowang"));
//读取cell中的所有历史版本数据,不设置此配置的时候默认只读取最新版本的数据
//可以通过get.readVersions(2)来指定获取多少个历史版本的数据
get.readAllVersions();
Result result = table.get(get);
//获取指定列族中指定列的所有历史版本数据,前提是要设置get.readAllVersions()或者get.readVersions(2),否则只会获取最新数据
List<Cell> columnCells = result.getColumnCells(Bytes.toBytes("info"), Bytes.toBytes("age"));
for (Cell cell: columnCells) {
byte[] value_bytes = CellUtil.cloneValue(cell);
long timestamp = cell.getTimestamp();
System.out.println("值为:"+new String(value_bytes)+",时间戳:"+timestamp);
}
//关闭table连接
table.close();
}
/**
* 查询数据
* @param conn
* @throws IOException
*/
private static void get(Connection conn) throws IOException {
//获取Table,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Get对象
Get get = new Get(Bytes.toBytes("laowang"));
//【可选】可以在这里指定要查询指定Rowkey数据哪些列族中的列
//如果不指定,默认查询指定Rowkey所有列的内容
get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"));
get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("sex"));
Result result = table.get(get);
//如果不清楚HBase中到底有哪些列族和列,可以使用listCells()获取所有cell(单元格),cell对应的是某一列的数据
List<Cell> cells = result.listCells();
for (Cell cell : cells) {
//注意:下面获取的信息都是字节类型的,可以通过new String(bytes)转为字符串
//列族
byte[] famaily_bytes = CellUtil.cloneFamily(cell);
//列
byte[] column_bytes = CellUtil.cloneQualifier(cell);
//值
byte[] value_bytes = CellUtil.cloneValue(cell);
System.out.println("列族:"+new String(famaily_bytes)+",列:"+new String(column_bytes)+",值:"+new String(value_bytes));
}
System.out.println("==============================================");
//如果明确知道HBase中有哪些列族和列,可以使用getValue(family,qualifier)直接获取指定列族中指定列的数据
byte[] age_bytes = result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age"));
System.out.println("age列的值:"+new String(age_bytes));
//关闭table连接
table.close();
}
/**
* 添加数据
*
* @param conn
* @throws IOException
*/
private static void put(Connection conn) throws IOException {
//获取Table,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回put对象
Put put = new Put(Bytes.toBytes("laowang"));
//向put对象中指定列族、列、值
//put 'student','laowang','info:age','18'
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("18"));
//put 'student','laowang','info:sex','man'
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("sex"), Bytes.toBytes("man"));
//put 'student','laowang','level:class','A'
put.addColumn(Bytes.toBytes("level"), Bytes.toBytes("class"), Bytes.toBytes("A"));
//向表中添加数据
table.put(put);
//关闭table连接
table.close();
}
/**
* 获取连接
*
* @return
* @throws IOException
*/
private static Connection getConn() throws IOException {
//获取配置
Configuration conf = HBaseConfiguration.create();
//指定HBase使用的zk的地址,多个用逗号隔开
conf.set("hbase.zookeeper.quorum", "bigdata01:2181");
//指定HBase在hdfs上的根目录
conf.set("hbase.rootdir", "hdfs://bigdata01:9000/hbase");
//创建HBase连接,负责对HBase中的数据的一些增删改查(DML操作)
return ConnectionFactory.createConnection(conf);
}
}