一、HBase配置
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
- 将hbase-site.xml文件放入resource文件夹中
- 创建ConnectionUtil类用于获取Connection对象
package tiger.hbase.tools;
/*
* 1、创建和关闭Connection对象
*
* 2、如何在HBase中创建一个Configuration对象
* 可以使用HBasseConfiguration.create(),返回的Configuration,既包含hadoop的8个配置文件的参数,
* 又包含hbase-default.xml和hbase-site.xml中所有的参数配置
* */
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import java.io.IOException;
public class ConnectionUtil {
// 创建一个Connection对象
public static Connection getConn() throws IOException {
return ConnectionFactory.createConnection();
}
public static void close(Connection conn) throws IOException {
if (conn != null) {
conn.close();
}
}
}
package com.tiger;
import org.junit.Test;
import tiger.hbase.tools.ConnectionUtil;
import java.io.IOException;
public class TestConn {
@Test
public void test() throws IOException {
System.out.println(ConnectionUtil.getConn());
}
}
二、操作NameSpace
package tiger.hbase.tools;
/*
* 1、创建/删除/查询/判断是否存在名称空间
*
* hbase shell:开启一个客户端对象
* hbase shell:create_namespace 库名
*
* 2、Admin:提供对HBase管理的一些api
* 例如:创建,删除,查询表等
* 可以使用Connection.getAdmin()来获取Admin的一个实例,使用完成后,调用close关闭
*
* 3、Connection,Connection代表客户端和集群的一个连接,这个连接包含对master的连接,和zk的连接
* Connection可以使用ConnectionFactory来创建
* Connection的创建是重量级的,因此建议一个应用只创建一个Connection对象,Connection是线程安全的,
* 可以在多个线程中共享同一个Connection实例
* Connection的生命周期也是用户自己控制
*
* 从Connection中获取Table和Admin对象的实例,Table和Admin对象的创建是轻量级,且不是线程安全的,
* 因此不建议池化或缓存Table和Admin对象的实例,每个线程有自己的Table和Admin对象
* 4、NamespaceDescriptor:用来代表和定义名称空间
*
*
* */
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class NameSpaceUtil {
private static Logger logger = LoggerFactory.getLogger(NameSpaceUtil.class);
// 查询所有的名称空间
public static List<String> listNameSpace(Connection conn) throws IOException {
List<String> nss = new ArrayList<>();
// 提供一个admin
Admin admin = conn.getAdmin();
NamespaceDescriptor[] namespaceDescriptors = admin.listNamespaceDescriptors();
for (NamespaceDescriptor namespaceDescriptor : namespaceDescriptors) {
// 取出每个库描述中库的名称
nss.add(namespaceDescriptor.getName());
}
// 关闭admin
admin.close();
return nss;
}
// 判断库是否存在
public static boolean ifNSExists(Connection conn, String nsname) throws IOException {
// 库名校验
if (StringUtils.isBlank(nsname)) {
logger.error("请输入正确的库名");
// 在后台显示库名非法
return false;
}
// 提供一个admin
Admin admin = conn.getAdmin();
// 根据库名来查询对应的NS,如果找不到就抛异常
try {
admin.getNamespaceDescriptor(nsname);
return true;
} catch (Exception e) {
return false;
} finally {
admin.close();
}
}
// 创建库
public static boolean createNS(Connection conn, String nsname) throws IOException {
// 验证库名是否有问题
if (StringUtils.isBlank(nsname)) {
logger.error("请输入正确的库名");
// 在后台显示库名非法
return false;
}
// 提供一个admin
Admin admin = conn.getAdmin();
// 新建库
try {
// 先创建库的定义或描述
NamespaceDescriptor descriptor = NamespaceDescriptor.create(nsname).build();
admin.createNamespace(descriptor);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
admin.close();
}
}
//删除库
public static boolean deleteNs(Connection conn, String nsname) throws IOException {
// 验证库名是否有问题
if (StringUtils.isBlank(nsname)) {
logger.error("请输入正确的库名");
// 在后台显示库名非法
return false;
}
// 提供一个admin
Admin admin = conn.getAdmin();
// 只能删除空库,判断当前库是否为空,不为空无法删除
// 查询当前库下有哪些表
List<String> tableInNameSpace = getTableInNameSpace(conn, nsname);
if (tableInNameSpace.size() == 0) {
admin.deleteNamespace(nsname);
admin.close();
return true;
} else {
admin.close();
logger.error(nsname + "库非空,无法删除!");
return false;
}
}
// 查询库下有哪些表
public static List<String> getTableInNameSpace(Connection conn, String nsname) throws IOException {
// 验证库名是否有问题
if (StringUtils.isBlank(nsname)) {
logger.error("请输入正确的库名");
// 在后台显示库名非法
return null;
}
List<String> tables = new ArrayList<>();
Admin admin = conn.getAdmin();
// 查询当前库所有表
HTableDescriptor[] tableDescriptors = admin.listTableDescriptorsByNamespace(nsname);
for (HTableDescriptor tableDescriptor : tableDescriptors) {
tables.add(tableDescriptor.getNameAsString());
}
admin.close();
return tables;
}
}
package com.tiger;
import org.apache.hadoop.hbase.client.Connection;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import tiger.hbase.tools.ConnectionUtil;
import tiger.hbase.tools.NameSpaceUtil;
import java.io.IOException;
public class TestNameSpaces {
private static Connection conn;
@Before
public void init() throws IOException {
conn = ConnectionUtil.getConn();
}
@Test
public void testListNss() throws IOException {
System.out.println(NameSpaceUtil.listNameSpace(conn));
}
@Test
public void testIfExistsNSs() throws IOException {
System.out.println(NameSpaceUtil.ifNSExists(conn, "default"));
}
@Test
public void testCreateNs() throws IOException {
System.out.println(NameSpaceUtil.createNS(conn, "ns1"));
}
@Test
public void testTableInNS() throws IOException {
System.out.println(NameSpaceUtil.getTableInNameSpace(conn, "default"));
}
@Test
public void testDeleteNS() throws IOException {
System.out.println(NameSpaceUtil.deleteNs(conn, "ns1"));
}
@After
public void close() throws IOException {
ConnectionUtil.close(conn);
}
}
三、表的操作
package tiger.hbase.tools;
/*
* 创建/删除表
*
* 1、TableName:代表表名
* 调用valueof(String 库名, String 表名),返回表名
* 如果库名为null,此时使用default为库名
*
* 2、HTableDescriptor:代表表的细节,包含表中列族的描述
*
* */
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class TableUtil {
private static Logger logger = LoggerFactory.getLogger(TableUtil.class);
// 验证表名是否合法并返回
public static TableName checkTableName(String tableName, String nsname) {
if (StringUtils.isBlank(tableName)) {
logger.error("请输入正确的表名!");
return null;
}
return TableName.valueOf(nsname, tableName);
}
// 判断表是否存在
public static boolean ifTableExists(Connection conn, String tablename, String nsname) throws IOException {
// 校验表名
TableName tn = checkTableName(tablename, nsname);
if (tn == null) {
return false;
}
Admin admin = conn.getAdmin();
// 判断表是否存在
boolean tableExists = admin.tableExists(tn);
admin.close();
return tableExists;
}
// 创建表
public static boolean createTable(Connection conn, String tablename, String nsname, String...cfs) throws IOException {
// 校验表名
TableName tn = checkTableName(tablename, nsname);
if (tn == null) {
return false;
}
// 至少需要传入一个列族
if (cfs.length < 1) {
logger.error("至少需要指定一个列族!");
return false;
}
Admin admin = conn.getAdmin();
// 创建表的描述
HTableDescriptor hTableDescriptor = new HTableDescriptor(tn);
// 将列族的描述添加到表的描述中
for (String cf : cfs) {
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);
// 添加列族的设置
hColumnDescriptor.setMaxVersions(10);
hColumnDescriptor.setMinVersions(3);
hTableDescriptor.addFamily(hColumnDescriptor);
}
// 根据表的描述创建表
admin.createTable(hTableDescriptor);
admin.close();
return true;
}
// 删除表
public static boolean dropTable(Connection conn, String tablename, String nsname) throws IOException {
// 检查表是否存在
if (!ifTableExists(conn, tablename, nsname)) {
return false;
}
TableName tn = checkTableName(tablename, nsname);
Admin admin = conn.getAdmin();
// 删除之前需要禁用表
admin.disableTable(tn);
// 删除表
admin.deleteTable(tn);
return true;
}
}
package com.tiger;
import org.apache.hadoop.hbase.client.Connection;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import tiger.hbase.tools.ConnectionUtil;
import tiger.hbase.tools.TableUtil;
import java.io.IOException;
public class TestTableUtil {
private static Connection conn;
@Before
public void init() throws IOException {
conn = ConnectionUtil.getConn();
}
@Test
public void testTableExists() throws IOException {
System.out.println(TableUtil.ifTableExists(conn, "t2", null));
}
@Test
public void testCreateTable() throws IOException {
System.out.println(TableUtil.createTable(conn, "t2", null, "cf1","cf2"));
}
@Test
public void testDropTable() throws IOException {
System.out.println(TableUtil.dropTable(conn, "t2", null));
}
@After
public void close() throws IOException {
ConnectionUtil.close(conn);
}
}
四、数据操作
package tiger.hbase.tools;
/*
* 数据的增删改查,需要使用的是Table对象
*
* 1、Put:代表对单行数据的put操作
*
* 2、在HBase中操作数据都是以byte[]形式存在,需要吧常用的数据类型转换为byte[]
* hbase提供了一个Bytes工具类
* Bytes.toBytes(x)基本数据类型转byte[]
* Bytes.toXxx(x) 从bytes类型转换为其他类型
*
* 3、Get:代表对单行数据的get操作
*
* 4、Result:scan或get单行的所有的记录
*
* 5、Cell:代表一个单元格,hbase提供了CellUtil.clonexxx(Cell),来获取cell中的一些列族,列名和值属性。
* */
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class DataUtil {
//先获取到表的table对象
public static Table getTable(Connection conn,String tableName,String nsname) throws IOException {
//验证表名是否合法
TableName tn = TableUtil.checkTableName(tableName, nsname);
if (tn == null) {
return null;
}
//根据TableName获取对应的Table
return conn.getTable(tn);
}
//put 表名,rowkey,列名(列族名:列名),value
public static void put(Connection conn,String tableName,String nsname,String rowkey,String cf,
String cq,String value) throws IOException {
//获取表对象
Table table = getTable(conn, tableName, nsname);
if (table==null) {
return;
}
//创建一个Put对象
Put put = new Put(Bytes.toBytes(rowkey));
//向put中设置cell的细节信息
put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cq), Bytes.toBytes(value));
//.addColumn(family, qualifier, value)
table.put(put);
table.close();
}
// get 表名 rowkey
public static void get(Connection conn,String tableName,String nsname,String rowkey) throws IOException {
//获取表对象
Table table = getTable(conn, tableName, nsname);
if (table==null) {
return ;
}
Get get = new Get(Bytes.toBytes(rowkey));
//设置单行查询的详细信息
//设置查哪个列
//get.addColumn(family, qualifier)
//设置查哪个列族
//get.addFamily(family)
//只查某个时间戳的数据
//get.setTimeStamp(timestamp)
//设置返回的versions
//get.setMaxVersions(maxVersions)
Result result = table.get(get);
//System.out.println(result);
parseResult(result);
table.close();
}
// scan '表名', {STARTROW => x, STOPROW => X, LIMIT => 1}
public static void scan(Connection conn, String tableName, String nsname) throws IOException {
//获取表对象
Table table = getTable(conn, tableName, nsname);
if (table==null) {
return ;
}
// 构建scan对象
Scan scan = new Scan();
// 设置扫描的起始行
// scan.setStartRow(startRow);
// 设置扫描的结束行
// scan.setStopRow(stopRow);
// 结果集扫描器,多行result对象的集合
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
parseResult(result);
}
// 关闭表
table.close();
}
// delete '表名','rowkey',[列族][列][ts]
public static void delete(Connection conn, String tableName, String nsname, String rowkey) throws IOException {
//获取表对象
Table table = getTable(conn, tableName, nsname);
if (table==null) {
return ;
}
// 构建delete对象
Delete delete = new Delete(Bytes.toBytes(rowkey));
// 设置delete的参数
// 删除某个具体的列,为此列的最新的cell,添加一条type=DELETE的标记,只能删除最新的一条记录,如果有历史版本的记录无法删除
// delete.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("age"));
// 删除指定列的所有版本的数据,为当前列生成一个type=DeleteColumn的标记
// delete.addColumns(Bytes.toBytes("cf1"), Bytes.toBytes("age"));
// 删除整个列族
delete.addFamily(Bytes.toBytes("cf2"));
table.delete(delete);
// 关闭表
table.close();
}
//遍历result
public static void parseResult(Result result) {
if (result != null) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
System.out.println("行:"+Bytes.toString(CellUtil.cloneRow(cell))+
" 列族:"+Bytes.toString(CellUtil.cloneFamily(cell))+" 列名:"+
Bytes.toString(CellUtil.cloneQualifier(cell))+
" 值:"+Bytes.toString(CellUtil.cloneValue(cell)));
}
}
}
}
package com.tiger;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import tiger.hbase.tools.ConnectionUtil;
import tiger.hbase.tools.DataUtil;
import java.io.IOException;
public class TestDataUtil {
private Connection conn;
@Before
public void init() throws IOException {
conn=ConnectionUtil.getConn();
}
@After
public void close() throws IOException {
ConnectionUtil.close(conn);
}
@Test
public void testPut() throws IOException {
DataUtil.put(conn, "t1", null, "b1", "cf1", "name", "jack");
}
@Test
public void testGet() throws IOException {
DataUtil.get(conn, "t1", null, "r1");
}
@Test
public void testScan() throws IOException {
DataUtil.scan(conn, "t1", null);
}
@Test
public void testDelete() throws IOException {
DataUtil.delete(conn, "t1", null, "a1");
}
}