import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class HBaseUtils {
private static ThreadLocal<Connection> connHolder = new ThreadLocal<Connection>();
private static Connection connection = null;
private HBaseUtils() {
}
/**
* 获取hbase连接对象
*/
public static Connection getHbaseConnection() throws IOException {
Connection conn = connHolder.get();
if(conn ==null){
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "192.168.1.102");
conf.set("hbase.zookeeper.property.clientPort", "2181");
conn = ConnectionFactory.createConnection(conf);
connHolder.set(conn);
}
return conn;
}
/**
* 关闭连接
*/
public static void close() throws IOException {
Connection conn = connHolder.get();
if(conn!=null){
conn.close();
connHolder.remove();
}
}
/**
* 判断表是否存在
*/
public static boolean isTableExist(String tableName) throws MasterNotRunningException,
ZooKeeperConnectionException, IOException {
//在HBase中管理、访问表需要先创建HBaseAdmin对象
//Connection connection = ConnectionFactory.createConnection(conf);
//HBaseAdmin admin = (HBaseAdmin) connection.getAdmin();
Connection conn = connHolder.get();
Admin admin = conn.getAdmin();
return admin.tableExists(TableName.valueOf(tableName));
}
/**
* 创建表
*/
public static void createTable(String tableName, String... columnFamily) throws
MasterNotRunningException, ZooKeeperConnectionException, IOException {
Connection conn = connHolder.get();
Admin admin = conn.getAdmin();
//判断表是否存在
if (isTableExist(tableName)) {
System.out.println("表" + tableName + "已存在");
//System.exit(0);
} else {
//创建表属性对象,表名需要转字节
HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(tableName));
//创建多个列族
for (String cf : columnFamily) {
descriptor.addFamily(new HColumnDescriptor(cf));
}
//根据对表的配置,创建表
admin.createTable(descriptor);
System.out.println("表" + tableName + "创建成功!");
}
}
/**
* 删除表
*/
public static void dropTable(String tableName) throws MasterNotRunningException,
ZooKeeperConnectionException, IOException {
Connection conn = connHolder.get();
Admin admin = conn.getAdmin();
if (isTableExist(tableName)) {
admin.disableTable(TableName.valueOf(tableName));
admin.deleteTable(TableName.valueOf(tableName));
System.out.println("表" + tableName + "删除成功!");
} else {
System.out.println("表" + tableName + "不存在!");
}
}
/**
* 向表中插入数据
*/
public static void addRowData(String tableName, String rowKey, String columnFamily, String
column, String value) throws IOException {
Connection conn = connHolder.get();
//创建HTable对象
Table table = conn.getTable(TableName.valueOf(tableName));
//向表中插入数据
Put put = new Put(Bytes.toBytes(rowKey));
//向Put对象中组装数据
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column), Bytes.toBytes(value));
table.put(put);
table.close();
System.out.println("插入数据成功");
}
/**
* 获取所有数据
*/
public static void getAllRows(String tableName) throws IOException {
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
//得到用于扫描region的对象
Scan scan = new Scan();
//使用HTable得到resultcanner实现类的对象
ResultScanner resultScanner = table.getScanner(scan);
for (Result result : resultScanner) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
//得到rowkey
System.out.println("行键:" + Bytes.toString(CellUtil.cloneRow(cell)));
//得到列族
System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
}
/**
* 通过scan查询数据
*/
public static void getDataByScanFilter(String tableName) throws IOException {
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
//创建用于扫描region的对象
Scan scan = new Scan();
//设置Filter(较慢)
//字节数组比较器
BinaryComparator bc = new BinaryComparator(Bytes.toBytes("1001"));
//正则表达式比较器
RegexStringComparator rc = new RegexStringComparator("^\\d{3}$");
Filter f1 = new RowFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL,bc);
Filter f2 = new RowFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL,rc);
//设置单个filter
//scan.setFilter(f1);
//设置多个fiter
/**
* 多个filter之间的逻辑关系,相当于java中的与和或
* (AND)
* MUST_PASS_ALL,
* (OR)
* MUST_PASS_ONE
*/
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filterList.addFilter(f1);
filterList.addFilter(f2);
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
//得到rowkey
System.out.println("行键:" + Bytes.toString(CellUtil.cloneRow(cell)));
//得到列族
System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
}
/**
* 获取一行数据
*/
public static void getRow(String tableName, String rowKey) throws IOException{
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
//get.setMaxVersions();显示所有版本
//get.setTimeStamp();显示指定时间戳的版本
Result result = table.get(get);
for(Cell cell : result.rawCells()){
System.out.println("行键:" + Bytes.toString(result.getRow()));
System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
System.out.println("时间戳:" + cell.getTimestamp());
}
}
/**
* 获取某一行指定“列族:列”的数据
*/
public static void getRowQualifier(String tableName, String rowKey, String family, String
qualifier) throws IOException{
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));
Result result = table.get(get);
for(Cell cell : result.rawCells()){
System.out.println("行键:" + Bytes.toString(result.getRow()));
System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
/**
* 删除多行数据
*/
public static void deleteMultiRow(String tableName, String... rows) throws IOException{
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
List<Delete> deleteList = new ArrayList<Delete>();
for(String row : rows){
Delete delete = new Delete(Bytes.toBytes(row));
deleteList.add(delete);
}
table.delete(deleteList);
table.close();
}
/**
* 生成分区键
*/
public static byte[][] getRegionKeys(int regionCount){
byte[][] bs = new byte[regionCount-1][];
/*
此处的分区键使用了‘0|’、‘1|’,‘2|’,‘3|’的形式,使得0开头的rowkey可以进入该分区
因为Hbase中的rowkey是按照ANSCⅡ排序的,‘|’是ANSCⅡ中第二大的字符,第一大的是‘}’(其用来分割)
这样可以使得rowkey以0开头,后面的字符都比‘|’小,可以进入该分区
eg:0qqq --> 'q'<'|' 进入该分区
*/
for (int i = 0; i < regionCount - 1; i++) {
bs[i] = Bytes.toBytes(i + "|");
}
return bs;
}
public static void main(String[] args) {
String rowkey = "afei";
System.out.println(getRegionNum(rowkey,3));
}
/**
*生成分区号
*/
public static String getRegionNum(String rowkey,int regionCount){
int regionNum;
int hash = rowkey.hashCode();
if(regionCount > 0 && (regionCount & (regionCount - 1)) == 0){
//2^N
regionNum = hash & (regionCount - 1);
}else{
regionNum = hash % (regionCount);
}
return regionNum + "_" + rowkey;
}
}