HBaseAPI操作

一、HBase配置

  • 在idea中创建maven工程,导入以下依赖
<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");
    }

}

猜你喜欢

转载自blog.csdn.net/qq_38689352/article/details/113743825
今日推荐