Win下使用Java操作远程完全分布式集群中的HBase

基本原理介绍:
1.Java客户端其实就是shell客户端的一种实现,操作命令基本上就是shell客户端命令的一个映射。
2.Java客户端使用的配置信息是被映射到了HbaseConfiguration的实例对象中的,使用HBaseConfiguration.create()方法创建实例化对象的时候,会从classpath中获取hbase-site.xml文件并进行配置文件内容的读取。同时也会读取hadoop的配置文件信息。这里我们给定zookeeper的相关配置信息即可。
3.流程:先通过zookeeper拿到hbase:namespace的路径,然后从这个路径中拿到hbase:meta表的信息,接着就拿到了用户表的路径
——摘自kevin&learn

前提条件

  1. 本地Windows(7或10)系统下已经装好了JDK和Eclipse,笔者电脑JDK1.8。
  2. 已经有搭建好的完全分布式集群,并已经成功启动Hadoop,Zookeeper和HBase。笔者当前搭建好的集群是Hadoop-3.0.3Zookeeper-3.4.13HBase-2.1.0
  3. 本地已经成功连接到远程HBase,连接方法详见:《本地Java连接远程集群上的HBase》
HostnameIP
master10.0.86.245
ceph110.0.86.246
ceph210.0.86.221
ceph310.0.86.253

以下先逐个讲解每个操作的方法,文章最后附完整代码。

前言:建立连接和关闭连接

1.需要三个静态属性

public static Configuration configuration; //配置对象,用于管理配置信息(类似hbase-site.xml)
public static Connection connection;       //连接对象,用于连接数据库
public static Admin admin;                 //管理对象,用于管理表(如对表的增删改查)

2.创建连接(初始化)

public static void init(){
    	//1.根据hbase-site.xml文件初始化Configuration对象
        configuration  = HBaseConfiguration.create();
        configuration.set("hbase.rootdir","hdfs://master:9000/hbase");
        configuration.set("hbase.zookeeper.quorum", "master,ceph1,ceph2,ceph3");
		configuration.set("hbase.zookeeper.property.clientPort", "2181");
        try{
        	 //2.根据Configuration对象初始化Connection对象
            connection = ConnectionFactory.createConnection(configuration);
            //3.根据Connection对象获取Admin对象
            admin = connection.getAdmin(); 
            System.out.println("连接HBase成功.");
        }catch (IOException e){
            System.err.println("连接HBase失败.");
        }
    }

连接是否成功的关键代码是:

connection = ConnectionFactory.createConnection(configuration);

3.关闭连接
实际就是closeadminconnection

public static void close(){
    try{
        if(admin != null){
            admin.close();
        }
        if(null != connection){
            connection.close();
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

一、创建数据库表

在这里插入图片描述
查询新的API文档发现官网确实要在3.x版本中废弃1.x用的类和部分方法,遂笔者换了一个新的类和方法实现创建表功能。(注:以下为测试每个方法,所以在方法的开头结尾加上了数据库的创建连接和关闭连接,实际应用中无需这样)

public static void createTable(String myTableName,String[] colFamily) throws IOException {
    init();  //创建连接
    TableName tableName = TableName.valueOf(myTableName); 
    if(admin.tableExists(tableName)){ //若要创建的表名存在,则无需创建新表
        System.out.println("talbe is exists!");
    }else {  //若要创建的表名不存在,则创建新表
        TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);  //创建新表实例
        for(String str:colFamily){  
            ColumnFamilyDescriptor columnfamily = ColumnFamilyDescriptorBuilder.of(str);  //根据字符串列簇名分别创建新的列簇
            tableDescriptor.setColumnFamily(columnfamily); //把新列簇依次添加到新表实例中
        }
        admin.createTable(tableDescriptor.build()); //把创建的新表实例添加到HBase中
        System.out.println("create table success");
    }
    close();  //关闭连接
}

示例:创建一个名字为ls_world表,列簇分别为w1w2

$ create 'ls_world','w1','w2'
createTable("ls_world",new String[]{"w1","w2"});

HBase shellhttp://10.0.86.245:16010可看到
在这里插入图片描述
补充解释:
1.从HBase API上可以看到,newBuilder方法返回的是TableDescriptorBuilder,所以最后填入admin.createTable(tableDescriptor.build());方法中加了build()方法以保证返回类型是TableDescriptor

TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);

31
2.从HBase API上可以看到,ColumnFamilyDescriptorBuilder对象可以调用of()方法,填入字符串参数即可返回ColumnFamilyDescriptor对象,可直接传入setColumnFamily()方法。

ColumnFamilyDescriptor columnfamily = ColumnFamilyDescriptorBuilder.of(str);

2121

二、删除数据库表

和直接在HBase shell操作一样,需要先disable,再delete

public static void deleteTable(String tableName) throws IOException {
    init();
    TableName tn = TableName.valueOf(tableName);
    if (admin.tableExists(tn)) {
        admin.disableTable(tn);
        admin.deleteTable(tn);
    }
    close();
}

示例:删除一个名字为Score表。

$ disable 'Score'
$ drop 'Score'
deleteTable("Score");

三、向某行某列插入数据

public static void insertRow(String tableName,String rowKey,String colFamily,String col,String val) throws IOException {
    init();
    Table table = connection.getTable(TableName.valueOf(tableName)); //获取表
    Put put = new Put(rowKey.getBytes());  //创建put实例,添加rowKey参数
    put.addColumn(colFamily.getBytes(), col.getBytes(), val.getBytes()); //添加其余参数
    table.put(put); //插入到表中
    table.close();
    close();
}

示例:向ls_world表的w1列簇中插入以下数据。

$ put 'ls_world','95001','w1:name','Jack'
insertRow("ls_world", "95001", "w1", "name", "Jack");

在这里插入图片描述

四、删除表中数据

删除指定列簇指定列的数据

    public static void deleteRow(String tableName,String rowKey,String colFamily,String col) throws IOException {
        init();
        Table table = connection.getTable(TableName.valueOf(tableName));
        Delete delete = new Delete(rowKey.getBytes());        
        if(col.equals("")) //删除指定列族的所有数据
        	delete.addFamily(colFamily.getBytes());
        else               //删除指定列的数据
            delete.addColumn(colFamily.getBytes(), col.getBytes());
 
        table.delete(delete);
        table.close();
        close();
    }

示例:删除ls_world表的w1列簇中age列数据,或w1列簇中所有数据数据。

$ delete 'ls_world','95001','w1:age'
$ delete 'ls_world','95001','w1'
deleteRow("ls_world", "95001", "w1", "age");
deleteRow("ls_world", "95001", "w1", "");

五、根据行键rowkey查找数据

    public static void getData(String tableName,String rowKey,String colFamily,String col)throws  IOException{
        init();
        Table table = connection.getTable(TableName.valueOf(tableName));
        Get get = new Get(rowKey.getBytes());
        if(col.equals(""))
        	get.addFamily(colFamily.getBytes());
        else 
        	get.addColumn(colFamily.getBytes(),col.getBytes());
        Result result = table.get(get);
        showCell(result);  //格式化输出
        table.close();
        close();
    }
    public static void showCell(Result result){  //格式化输出
        Cell[] cells = result.rawCells();
        for(Cell cell:cells){
        	System.out.println(new String(CellUtil.cloneFamily(cell))+":"
                              +new String(CellUtil.cloneQualifier(cell))
                              +"        timestamp="
                              +cell.getTimestamp()+", value="
                              +new String(CellUtil.cloneValue(cell)));
        }
    }

示例:查询ls_world95001行的w1列簇中所有数据,或w1列簇中age列数据。

$ get 'ls_world','95001','w1'
$ get 'ls_world','95001','w1:age'
getData("ls_world", "95001", "w1", "");
getData("ls_world", "95001", "w1", "age");

查询结果如下:
在这里插入图片描述
对照HBase shell中的查询结果相同。
在这里插入图片描述

六、列出当前所有数据库表

    public static void listTables() throws IOException {
        init();
        TableName tablenames[] = admin.listTableNames();
        for(TableName tablename:tablenames){
        	System.out.println(tablename.getNameAsString());
        }
        close();
    }

示例:列出当前所有数据库表。

$ list 'ls_world'
listTables()

查询结果如下:
在这里插入图片描述
对照HBase shell中的查询结果相同。
在这里插入图片描述

完整代码如下

package test1;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import java.io.IOException;
 
public class testOne{
    public static Configuration configuration;
    public static Connection connection;
    public static Admin admin;
    public static void main(String[] args)throws IOException{
    	//init();
    	//close();
    	//createTable("ls_world",new String[]{"w1","w2"});
    	//insertRow("ls_world", "95001", "w2", "age", "22");
    	//insertRow("ls_world", "95001", "w2", "friend", "eeeea");
    	//deleteTable("Score");
    	//deleteRow("ls_world", "95001", "w1", "");
    	//getData("ls_world", "95001", "w1", "age");
    	listTables();
    }
    //建立连接
    public static void init(){
    	// 根据 hbase-site.xml 文件初始化 Configuration 对象
        configuration  = HBaseConfiguration.create();
        configuration.set("hbase.rootdir","hdfs://master:9000/hbase");
        configuration.set("hbase.zookeeper.quorum", "master,ceph1,ceph2,ceph3");
		configuration.set("hbase.zookeeper.property.clientPort", "2181");
        try{
        	// 根据 Configuration 对象初始化 Connection 对象
            connection = ConnectionFactory.createConnection(configuration);
            admin = connection.getAdmin();
            System.out.println("连接HBase成功.");
        }catch (IOException e){
            System.err.println("连接HBase失败.");
        }
    }
    //关闭连接
    public static void close(){
        try{
            if(admin != null){
                admin.close();
            }
            if(null != connection){
                connection.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    /**
     * 建表。HBase的表中会有一个系统默认的属性作为主键,主键无需自行创建,默认为put命令操作中表名后第一个数据,因此此处无需创建id列
     * @param myTableName 表名
     * @param colFamily 列族名
     * @throws IOException
     */
    public static void createTable(String myTableName,String[] colFamily) throws IOException {
 
        init();
        TableName tableName = TableName.valueOf(myTableName);
 
        if(admin.tableExists(tableName)){
            System.out.println("talbe is exists!");
        }else {
        	TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
            for(String str:colFamily){
            	ColumnFamilyDescriptor columnfamily = ColumnFamilyDescriptorBuilder.of(str);
            	tableDescriptor.setColumnFamily(columnfamily);
            }
            admin.createTable(tableDescriptor.build());
            System.out.println("create table success");
        }
        close();
    }
    /**
     * 删除指定表
     * @param tableName 表名
     * @throws IOException
     */
    public static void deleteTable(String tableName) throws IOException {
        init();
        TableName tn = TableName.valueOf(tableName);
        if (admin.tableExists(tn)) {
            admin.disableTable(tn);
            admin.deleteTable(tn);
        }
        close();
    }
    /**
     * 查看已有表
     * @throws IOException
     */
    public static void listTables() throws IOException {
        init();
        TableName tablenames[] = admin.listTableNames();
        for(TableName tablename:tablenames){
        	System.out.println(tablename.getNameAsString());
        }
        close();
    }
    /**
     * 向某一行的某一列插入数据
     * @param tableName 表名
     * @param rowKey 行键
     * @param colFamily 列族名
     * @param col 列名(如果其列族下没有子列,此参数可为空)
     * @param val 值
     * @throws IOException
     */
    public static void insertRow(String tableName,String rowKey,String colFamily,String col,String val) throws IOException {
        init();
        Table table = connection.getTable(TableName.valueOf(tableName));
        Put put = new Put(rowKey.getBytes());
        put.addColumn(colFamily.getBytes(), col.getBytes(), val.getBytes());
        table.put(put);
        table.close();
        close();
    }
    /**
     * 删除数据
     * @param tableName 表名
     * @param rowKey 行键
     * @param colFamily 列族名
     * @param col 列名
     * @throws IOException
     */
    public static void deleteRow(String tableName,String rowKey,String colFamily,String col) throws IOException {
        init();
        Table table = connection.getTable(TableName.valueOf(tableName));
        Delete delete = new Delete(rowKey.getBytes());        
        if(col.equals("")) //删除指定列族的所有数据
        	delete.addFamily(colFamily.getBytes());
        else               //删除指定列的数据
            delete.addColumn(colFamily.getBytes(), col.getBytes());
 
        table.delete(delete);
        table.close();
        close();
    }
    /**
     * 根据行键rowkey查找数据
     * @param tableName 表名
     * @param rowKey 行键
     * @param colFamily 列族名
     * @param col 列名
     * @throws IOException
     */
    public static void getData(String tableName,String rowKey,String colFamily,String col)throws  IOException{
        init();
        Table table = connection.getTable(TableName.valueOf(tableName));
        Get get = new Get(rowKey.getBytes());
        if(col.equals(""))
        	get.addFamily(colFamily.getBytes());
        else 
        	get.addColumn(colFamily.getBytes(),col.getBytes());
        Result result = table.get(get);
        showCell(result);
        table.close();
        close();
    }
    /**
     * 格式化输出
     * @param result
     */
    public static void showCell(Result result){
        Cell[] cells = result.rawCells();
        for(Cell cell:cells){
        	System.out.println(new String(CellUtil.cloneFamily(cell))+":"
                              +new String(CellUtil.cloneQualifier(cell))
                              +"        timestamp="
                              +cell.getTimestamp()+", value="
                              +new String(CellUtil.cloneValue(cell)));
        }
    }
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SL_World

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值