HBase Java API

前置条件

Hadoop 集群高可用搭建: Yarn资源调度器-CSDN博客

HBase集群搭建: HBase搭建-CSDN博客

环境准备

创建Maven项目HBaseApiDemo

修改pom.xml,添加依赖

复制代码
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>2.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>2.0.5</version>
        </dependency>

创建类HBaseApiDemo

java 复制代码
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.*;
import java.io.IOException;

public class HBaseApiDemo {
    //声明一个静态HBase的连接对象
    private static Connection connection;
    //通过静态代码块创建出来连接对象
    static {
        //创建配置文件对象
        Configuration configuration = HBaseConfiguration.create();
        //设置Zookeeper集群
        configuration.set("hbase.zookeeper.quorum","node2,node3,node4");
        //创建连接对象
        try {
            connection = ConnectionFactory.createConnection(configuration);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        System.out.println(connection);
    }
}

启动Hadoop集群:startha.sh(之前编写的启动脚本)

启动HBase集群start-hbase.sh

测试

运行HBaseApiDemo类中的main函数,返回connection的值,代表连接成功

java api 操作

Connection

客户端和集群的长连接,全局复用,不要随便关

Admin

Admin是 HBase Java 客户端提供的核心 API,专门用于执行集群管理类操作(都是集群级 / 元数据级操作,而非数据读写),可以理解为"管理遥控器"。Admin必须通过 Connection.getAdmin() 创建。它是轻量级对象,创建 / 销毁开销极低,每次执行管理操作后都要要close(),避免资源泄漏;

核心操作:

  • 命名空间管理 :创建 / 删除 / 修改命名空间(如 createNamespacedeleteNamespace);
  • 表管理 :建表、删表、修改表结构、判断表是否存在(如 createTabletableExists);
  • 集群状态查询:查看 Region 分布、Master 状态、集群配置等;
  • 权限管理 :给用户 / 表分配权限(如 grantrevoke);
  • 其他管理操作:手动触发 Region 拆分 / 合并、刷盘、日志清理等。

创建命名空间

在HBaseApiDemo类中添加创建命名空间的方法

java 复制代码
    /**创建命名空间
     * @param nameSpace:命名空间的名称
     * @throws IOException
     */
    public static void createNameSpace(String nameSpace) throws IOException {
        //1.获取HBaseAdmin对象:对象命名空间、表元数据级的CRUD操作使用
        Admin admin = connection.getAdmin();
        //2.创建命名空间的描述器对象
        NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(nameSpace).build();
        //3.创建命名空间
        try {
            admin.createNamespace(namespaceDescriptor);
            System.out.println("命名空间:"+nameSpace+"创建成功");
        }catch (NamespaceExistException nee){
            System.out.println("命名空间:"+nameSpace+"已经存在");
        }
        //4.关闭
        admin.close();
        //connection.close();
    }

测试

java 复制代码
    public static void main(String[] args) throws Exception {
        //System.out.println(connection);
        createNameSpace("testdb");
        if (connection != null){
            connection.close();
        }
    }

第二次运行结果如下:

删除命名空间

java 复制代码
    public static void deleteNameSpace(String nameSpace){
        //参数的合法性校验
        if (nameSpace == null || nameSpace.trim().isEmpty()){
            System.out.println("命名空间不能未空");
            return;
        }
        //声明Admin
        Admin admin = null;
        try {
            //创建HBaseAdmin对象
            admin = connection.getAdmin();
            //删除命名空间
            admin.deleteNamespace(nameSpace);
            System.out.println("命名空间:"+nameSpace+"删除成功");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭相关对象
            if (admin!=null){
                try {
                    admin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
//            if (connection!=null){
//                try {
//                    connection.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
        }
    }

测试

java 复制代码
    public static void main(String[] args) throws Exception {
        //System.out.println(connection);
        //createNameSpace("testdb");
        deleteNameSpace("testdb");
        if (connection != null){
            connection.close();
        }
    }

结果如下

判断表是否存在

java 复制代码
    /**
     * 判断一张表是否存在
     * @param tableName 表名
     */
    public  static boolean tableExist(String tableName){
        //1.声明admin对象
        Admin admin = null;
        try {
            //2.通过connection对象获取HBaseAdmin对象
            admin = connection.getAdmin();
            //3.将String类型tableName转化为TableName类的对象
            TableName tableNameobj = TableName.valueOf(tableName);
            //4.判断一个表是否存在
            return admin.tableExists(tableNameobj);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(admin!= null){
                try {
                    admin.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if (connection != null){
                try {
                    connection.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
        return false;
    } 

创建表

java 复制代码
    /**根据指定的表名和列族名称创建表
     * @param tableName:表名称
     * @param cfs:列族名
     */
    public static void createTable(String tableName,String...cfs) throws Exception {
        //1.判断表的名字是否为空
        if (tableName == null || tableName.trim().isEmpty()){
            System.out.println("表名不能为空");
            return;
        }
        //2.验证列族信息的合法性
        if (cfs ==null || cfs.length<=0){
            System.out.println("至少需要一个列族");
            return;
        }
        //3.将字符串类型的表名转为TableName对象
        TableName tableNameobj = TableName.valueOf(tableName);
        //4.获取admin对象
        Admin admin = connection.getAdmin();
        //5.判断表是否存在
        if(admin.tableExists(tableNameobj)){
            System.out.println("该表已经存在!");
            admin.close();
            //connection.close();
            return;
        }
        //6.创建表描述器对象
        TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableNameobj);
        //7.遍历cfs,设置列族信息
        for (String cf:cfs){
            //8.使用列族名称,构造ColumnFamilyDescriptorBuilder对象
            ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(cf));
            //9.将列族信息添加到表描述器对象
            tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptorBuilder.build());
        }
        //10.tableDescriptorBuilder构造成TableDescriptor
        TableDescriptor tableDesc = tableDescriptorBuilder.build();
        //11.创建表
        admin.createTable(tableDesc);
        System.out.println("表:"+tableName+"创建成功!");
        //12.关闭资源
        admin.close();
//        connection.close();
    }

测试:

java 复制代码
    public static void main(String[] args) throws Exception {
        //System.out.println(connection);
        //createNameSpace("testdb");
        //deleteNameSpace("testdb");
        createTable("test","cf1","cf2");
        System.out.println(tableExist("test"));
        if (connection != null){
            connection.close();
        }
    }

测试结果如下:

这是第二次的运行结果

删除表

java 复制代码
    /**删除指定的表
     * @param tableName:表名称
     */
    public static void deleteTable(String tableName) throws IOException {
        //1.校验表名的合法性
        if(tableName == null || tableName.trim().isEmpty()){
            System.out.println("表名不能为空");
            return;
        }
        //2.判断表是否存在
        if (!tableExist(tableName)){
            System.out.println("指定的表已经不存在了!");
            return;
        }
        //3.获取Admin
        Admin admin = connection.getAdmin();
        //4.将string类型的tableName转化为TableName类型的对象
        TableName tableNameObj = TableName.valueOf(tableName);
        //5.禁用表
        admin.disableTable(tableNameObj);
        //6.删除表
        admin.deleteTable(tableNameObj);
        System.out.println("表:"+tableName+"删除成功!");
        //7.关闭资源
        admin.close();

    }

测试

java 复制代码
    public static void main(String[] args) throws Exception {
        deleteTable("test");
        if (connection != null){
            connection.close();
        }

    }

结果如下:

添加数据

java 复制代码
    /**
     * 添加数据
     * @param tableName:表名
     * @param cf:列族名称
     * @param cd:列描述符
     * @param rowKey:数据的唯一标示
     * @param value:值
     */
    public static void putCellData(String tableName,String cf,String cd,byte[] rowKey,byte[] value) throws IOException {
        //1.校验参数的合法性tableName,cf,cd
        // 校验表名:非空 + 非空白字符
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:表名(tableName)不能为空或空白字符");
        }
        // 校验列族:非空 + 非空白字符
        if (cf == null || cf.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列族名称(cf)不能为空或空白字符");
        }
        // 校验列名:非空 + 非空白字符
        if (cd == null || cd.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列描述符(cd/列名)不能为空或空白字符");
        }
        // 校验rowKey:字节数组不能为空(HBase中rowKey是核心标识,不允许空)
        if (rowKey == null || rowKey.length == 0) {
            throw new IllegalArgumentException("参数异常:rowKey(字节数组)不能为空");
        }
        // 校验value:字节数组允许为空(业务场景可能需要存空值),但建议做非空提示(可选)
        if (value == null) {
            System.out.println("警告:value为null,将向HBase写入空值");
            // 如果业务不允许存空值,可放开下面这行
            // throw new IllegalArgumentException("参数异常:value(字节数组)不能为空");
        }

        //2.将String类型的tableName转化为TableName类型的对象
        TableName tableNameObj = TableName.valueOf(tableName);
        //3.通过connection对象获取HTable对象,对数据的CRUD都是通过该对象完成的
        Table table = connection.getTable(tableNameObj);
        //4.创建put对象
        Put put = new Put(rowKey);
        //5.将数据封装到put对象
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cd),value);
        //6.添加数据
        table.put(put);
        System.out.println("数据写入成功:表=" + tableName + ",rowKey=" + Bytes.toString(rowKey)
                + ",列族=" + cf + ",列名=" + cd);
        //7.关闭资源
        table.close();
    }

测试

java 复制代码
    public static void main(String[] args) throws Exception {
        createTable("test","cf1","cf2");
        putCellData("test","cf1","name",Bytes.toBytes("1001"),Bytes.toBytes("wusen"));
        if (connection != null){
            connection.close();
        }

    }

结果

get数据查询

java 复制代码
    /**
     * get查询一个单元格中的数据
     * @param tableName 表名称
     * @param rowKey 数据的唯一标识
     * @param cf 列族名称
     * @param cd 列描述符名称
     */
    public static void getData(String tableName,String rowKey,String cf,String cd) throws IOException {
        //1.参数校验
        // 校验表名:非空 + 非空白字符
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:表名(tableName)不能为空或空白字符");
        }
        // 校验列族:非空 + 非空白字符
        if (cf == null || cf.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列族名称(cf)不能为空或空白字符");
        }
        // 校验列名:非空 + 非空白字符
        if (cd == null || cd.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列描述符(cd/列名)不能为空或空白字符");
        }
        // 校验rowKey:字节数组不能为空(HBase中rowKey是核心标识,不允许空)
        if (rowKey == null || rowKey.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:rowKey(字节数组)不能为空");
        }
        //2.获取HTable对象
        Table table = connection.getTable(TableName.valueOf(tableName));
        //3.创建Get对象
        Get get = new Get(Bytes.toBytes(rowKey));
        //4.指定查询的列族,不指定的话获取rowKey对应这条数据的所有列族下的数据
        get.addFamily(Bytes.toBytes(cf));
        //5.指定列描述符 ,不设置该值则查询对应列族下的所有列的数据
        get.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cd));
        //6.执行查询
        Result result = table.get(get);
        //7.解析result对象
        for (Cell cell:result.rawCells()){
            System.out.println("row:"+Bytes.toString(CellUtil.cloneRow(cell))+

                    ",cf:"+Bytes.toString(CellUtil.cloneFamily(cell))+

                    ",cd:"+Bytes.toString(CellUtil.cloneQualifier( cell))+

                    ",value:"+Bytes.toString(CellUtil.cloneValue(cell)));
        }
        table.close();


    }

测试

java 复制代码
    public static void main(String[] args) throws Exception {
        getData("test","1001","cf1","name");
        if (connection != null){
            connection.close();
        }

    }

结果

scan数据查询

java 复制代码
   /**
     *scan扫描表数据
     * @param tableName:表的名称
     * @param startRow:起始的rowKey 包含
     * @param stopRow:结束的rowKey 包含
     */
    public static void scanTableData(String tableName,String startRow,String stopRow) throws IOException {
        //1.参数的校验
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("表名不能为空或空白字符");
        }
        //2.获取table对象
        Table table = connection.getTable(TableName.valueOf(tableName));
        //3.创建scan对象
        Scan scan = new Scan();
        //4.设置查询的范围
        byte[] startRowBytes = startRow == null ? null : Bytes.toBytes(startRow.trim());
        byte[] stopRowBytes = stopRow == null ? null : Bytes.toBytes(stopRow.trim());
        //设置起始行:传null则从表的第一行开始扫描。包含startRow对应的数据
        if (startRowBytes!=null){
            scan.withStartRow(startRowBytes);
        }
        //设置结束行:传null则扫描到表的最后一行。
        if (stopRowBytes!=null){
            //默认不包含stopRow,第二个参数true包含stopRow,false不包含stopRow
            scan.withStopRow(stopRowBytes,true);
        }
        //5.执行查询操作
        ResultScanner resultScanner = table.getScanner(scan);
        //6.解析resultScanner
        for (Result result:resultScanner){
            //7.解析result对象
            for (Cell cell:result.rawCells()){
                System.out.println("rowkey:"+Bytes.toString(CellUtil.cloneRow(cell))+

                        ",family:"+Bytes.toString(CellUtil.cloneFamily (cell))+

                        ",qualifier:"+Bytes.toString(CellUtil.cloneQualifier(cell))+

                        ",value:"+Bytes.toString(CellUtil.cloneValue(cell)));
            }
        }
        table.close();
    }

测试

java 复制代码
    public static void main(String[] args) throws Exception {
        putCellData("test","cf1","name",Bytes.toBytes("1002"),Bytes.toBytes("帅哥"));
        putCellData("test","cf1","name",Bytes.toBytes("1003"),Bytes.toBytes("型男"));
        putCellData("test","cf1","name",Bytes.toBytes("1004"),Bytes.toBytes("男模"));
        scanTableData("test","","1004");
        if (connection != null){
            connection.close();
        }

    }

结果

删除数据

下面对deleteData实现了重载

java 复制代码
 /**
     * 删除整行数据
     * @param tableName 表名称
     * @param rowKey 代表对应行数据的唯一标识
     */
    public static void deleteData(String tableName,String rowKey) throws IOException {
        //参数的合法性校验
        if (tableName == null || tableName.trim().isEmpty()){
            throw new IllegalArgumentException("参数异常:表名(tableName)不能为空或空白字符");
        }
        if (rowKey == null || rowKey.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:rowKey(字节数组)不能为空");
        }
        //获取HTable对象
        Table table = connection.getTable(TableName.valueOf(tableName));
        //创建删除对象
        Delete delete = new Delete(Bytes.toBytes(rowKey));
        //删除
        table.delete(delete);
        table.close();
    }

    /**
     * 删除指定行的指定列族下所有的数据
     * @param tableName 表名称
     * @param rowKey 代表对应行数据的唯一标识
     * @param cf 列族名称
     */
    public static void deleteData(String tableName,String rowKey,String cf) throws IOException {
        //参数的合法性校验
        if (tableName == null || tableName.trim().isEmpty()){
            throw new IllegalArgumentException("参数异常:表名(tableName)不能为空或空白字符");
        }
        if (rowKey == null || rowKey.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:rowKey(字节数组)不能为空");
        }
        if (cf == null || cf.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列族名称(cf)不能为空或空白字符");
        }
        //获取HTable对象
        Table table = connection.getTable(TableName.valueOf(tableName));
        //创建删除对象
        Delete delete = new Delete(Bytes.toBytes(rowKey));
        //指定列族名称
        delete.addFamily(Bytes.toBytes(cf));
        //删除
        table.delete(delete);
        table.close();
    }

    /**
     * 删除指定行的指定列族指定列的数据
     * @param tableName:表名称
     * @param rowKey:代表对应行数据的唯一标识
     * @param cf:列族名称
     * @param cd:列描述符
     * @throws IOException
     */
    public static void deleteData(String tableName,String rowKey,String cf,String cd) throws IOException {
        //参数的合法性校验
        if (tableName == null || tableName.trim().isEmpty()){
            throw new IllegalArgumentException("参数异常:表名(tableName)不能为空或空白字符");
        }
        if (rowKey == null || rowKey.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:rowKey(字节数组)不能为空");
        }
        if (cf == null || cf.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列族名称(cf)不能为空或空白字符");
        }
        if (cd == null || cd.trim().isEmpty()) {
            throw new IllegalArgumentException("参数异常:列描述符(cd/列名)不能为空或空白字符");
        }
        //获取HTable对象
        Table table = connection.getTable(TableName.valueOf(tableName));
        //创建删除对象
        Delete delete = new Delete(Bytes.toBytes(rowKey));
        //指定列族名称
        delete.addFamily(Bytes.toBytes(cf));
        //知道列名称
        delete.addColumn(Bytes.toBytes(cf),Bytes.toBytes((cd)));
        //删除
        table.delete(delete);
        table.close();
    }

测试

java 复制代码
 public static void main(String[] args) throws Exception {
        deleteData("test","1004");
        if (connection != null){
            connection.close();
        }

    }
相关推荐
大尚来也2 小时前
看不见的加速器:深入理解 Linux 页缓存如何提升 I/O 性能
java·开发语言
zhougl9962 小时前
Java 常见异常梳理
java·开发语言·python
sensen_kiss2 小时前
Jupter Notebook 使用教程
大数据·人工智能·python·学习·数据分析
缘空如是2 小时前
基础工具之jsoup工具
java·jsoup·html解析
毕设源码-郭学长2 小时前
【开题答辩全过程】以 基于Nodejs的网上书店 为例,包含答辩的问题和答案
java·eclipse
八月瓜科技2 小时前
2026春晚机器人专利战:从舞台秀到资本竞逐的产业突围
大数据·人工智能·microsoft·机器人·娱乐
you-_ling2 小时前
Linux软件编程:Shell命令
java·linux·服务器
数智工坊2 小时前
【数据结构-栈、队列、数组】3.3栈在括号匹配-表达式求值上
java·开发语言·数据结构
凌康ACG2 小时前
Warm-Flow国产工作流引擎入门
java·工作流引擎·flowable·warm-flow