1.创建连接和admin
使用静态方法块,每次只连接一次。
private static Admin admin=null;
private static Connection connection=null;
static {
try {
//1.获取配置文件信息
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop102,hadoop103,hadoop104");
connection = ConnectionFactory.createConnection(configuration);
//2.获取管理员对象
admin = connection.getAdmin();
} catch (IOException e) {
e.printStackTrace();
}
}
2.关闭资源部分
单独创建一个函数,在所有操作执行完成后统一关闭
public static void close() {
if (admin != null) {
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.各种操作的API
3.1 查看表是否存在
public static boolean isTableExist(String tablename) throws IOException {
boolean b = admin.tableExists(TableName.valueOf(tablename));
return b;
}
3.2 创建表
public static void creatTable(String tablename,String...cfs) throws IOException {
//1.判断是否传入列族
if(cfs.length<=0){
System.out.println("缺少列族信息!");
return;
}
//2.判断表是否存在
if (isTableExist(tablename)){
System.out.println("表已存在!");
return;
}
//3.创建表描述器
HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(tablename));
for (String cf : cfs) {
//4.创建列族描述器
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);
//5.增加列族信息
hTableDescriptor.addFamily(hColumnDescriptor);
}
//6.创建表
admin.createTable(hTableDescriptor);
}
测试:
public static void main(String[] args) throws IOException {
System.out.println("表starmap 存在?:"+isTableExist("starmap"));
creatTable("starmap", "info1", "info2");
System.out.println("表starmap 存在?:"+isTableExist("starmap"));
close();
}
3.3 删除表
private static void deleteTable(String tablename) throws IOException {
//1.判断表是否存在
if (!isTableExist(tablename)) {
System.out.println("表不存在!");
return;
}
//2.表下线
admin.disableTable(TableName.valueOf(tablename));
//3.表删除
admin.deleteTable(TableName.valueOf(tablename));
}
3.4 创建命名空间
private static void creatNamespace(String ns) {
//创建命名空间描述器,因为命名空间描述器是私有的,创建起来比较复杂
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(ns).build();
//通过抓取异常来判断命名空间是否重复
try {
admin.createNamespace(namespaceDescriptor);
}catch (NamespaceExistException nse){
System.out.println("命名空间已存在!");
}
catch (IOException e) {
e.printStackTrace();
}
}
在命名空间下建表和在命令行的格式是一样的命名空间:表明
即可
3.5 插入数据
private static void insetDatas(String tablename, String rowkey, String cf, String cn, String value) throws IOException {
//1.获取表对象
Table table = connection.getTable(TableName.valueOf(tablename));
//2.创建Put对象
Put put = new Put(Bytes.toBytes(rowkey));
//3.给put增加信息
put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cn), Bytes.toBytes(value));
//4.插入信息
table.put(put);
//5.关闭表连接
table.close();
}
测试:
insetDatas("stu", "1001", "info", "name", "eatfish");
tips:关于批量插入
- 对于同一个RowKey插入多个列,直接使用多个
put.addColumn()
即可 - 对于插入不同的RowKey,需要创建多个Put对象,生成一个Put的list,最后统一使用
table.put()
把整个list插入table。
3.6 数据的查找
列族和列是可以不用指定的,如果没有指定就返回整个RowKey的所有内容。
private static void getValue(String tablename, String rowkey, String cf, String cn) throws IOException {
//1.获取表对象
Table table = connection.getTable(TableName.valueOf(tablename));
Get get = new Get(Bytes.toBytes(rowkey));
//指定列族
//get.addFamily(Bytes.toBytes(cf));
//指定列族和列
get.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cn));
Result result = table.get(get);
for (Cell cell : result.rawCells()) {
System.out.println("CF:" + Bytes.toString(CellUtil.cloneFamily(cell)) + "CN:" + Bytes.toString(CellUtil.cloneQualifier(cell))
+ "Value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
3.7 数据表的查询
public static void scanTabel(String tablename) throws IOException {
Table table = connection.getTable(TableName.valueOf(tablename));
//Scan scan = new Scan();
//scan()方法可以设置开始的RowKey和结束的RowKey,左闭右开
Scan scan = new Scan(Bytes.toBytes("1002"), Bytes.toBytes("1004"));
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
System.out.println("CF:" + Bytes.toString(CellUtil.cloneFamily(cell)) + "\tCN:" + Bytes.toString(CellUtil.cloneQualifier(cell))
+ "\tValue:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
}
3.8 删除数据
private static void deleteData(String tablename, String rowkey, String cf, String cn) throws IOException {
Table table = connection.getTable(TableName.valueOf(tablename));
Delete delete = new Delete(Bytes.toBytes(rowkey));
//1.整个RowKey全部删除
//2.删除指定列的所有版本
//delete.addColumns(Bytes.toBytes(cf), Bytes.toBytes(cn));
//3.删除指定列最后一个时间戳的版本,那么scan后得到的该数据上一次修改前的内容。但是如果发生了刷写,删除之后也不会得到上一次修改前的内容了。
//delete.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cn));
//4.加上时间戳代表,删除在这个时间戳之前的所有的版本
//delete.addColumns(Bytes.toBytes(cf), Bytes.toBytes(cn),1576240458205L);
//5.删除整个列族
delete.addFamily(Bytes.toBytes(cf));
table.delete(delete);
table.close();
}
删除数据尽量不要使用addColumn()这个函数,因为它的结果(在不同时间段)会因为flush而导致不同,而且在意义上来说也没有很合理。