Hbase06:Java操作HBase:增删改查操作

本文档详细介绍了如何使用Java操作HBase,包括创建Maven项目,添加HBase和日志相关依赖,配置log4j.properties,创建HBase连接,对表进行增删改查操作,以及查询多版本数据的方法。同时,提供了完整的HBaseOp类代码示例,涵盖了表的创建和删除等DDL操作。
摘要由CSDN通过智能技术生成

一、创建maven项目

创建maven项目:db_hbase

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、添加依赖

由于需要操作HBase,所以需要在pom.xml中添加hbase-client依赖
在这里插入图片描述

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>2.2.7</version>
</dependency>

以及日志相关配置
在这里插入图片描述

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.10</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.10</version>
</dependency>

在resources目录中添加log4j.properties文件,文件内容如下:
在这里插入图片描述

log4j.rootLogger=info,stdout

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n

三、创建包和类

在src/main/java目录中创建package:com.imooc.hbase

创建类:HBaseOp

在这里插入图片描述

四、对表中的数据进行增删改查

1、首先需要获取HBase数据库连接

代码如下:

//获取配置
Configuration conf = HBaseConfiguration.create();
//指定HBase使用的zk的地址,多个用逗号隔开
conf.set("hbase.zookeeper.quorum", "bigdata01:2181");
//指定HBase在hdfs上的根目录
conf.set("hbase.rootdir","hdfs://bigdata01:9000/hbase");
//创建HBase连接,负责对HBase中数据的一些增删改查(DML操作)
Connection conn = ConnectionFactory.createConnection(conf);

注意:想要在哪台机器上执行代码操作HBase,一定要在这台机器上配置HBase集群所有节点的主机名和IP的映射关系

因为我们在连接HBase集群的时候在代码中指定的是zookeeper集群的地址信息,通过Zookeeper去查找HBase,HBase会在zookeeper里面存储自己的地址信息,存储的是主机名。
所以一定要在执行HBase代码的机器上配置HBase集群所有节点的主机名和IP的映射关系。

注意:代码在windows中执行的时候会提示缺少winutils.exe

[WARN] - Did not find winutils.exe: java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset.

这个警告信息不影响代码执行,在windows中执行会有这个提示,属于正常,把代码打包提交到集群上执行的时候就不会提示这个了,所以不用处理即可。

2、添加数据

//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回put对象
Put put = new Put(Bytes.toBytes("laowang"));
//向put对象中指定列族、列、值
//put 'student','laowang','info:age','18'
put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("18"));
//put 'student','laowang','info:sex','man'
put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("sex"),Bytes.toBytes("man"));
//put 'student','laowang','level:class','A'
put.addColumn(Bytes.toBytes("level"),Bytes.toBytes("class"),Bytes.toBytes("A"));
//向表中添加数据
table.put(put);
//关闭table连接
table.close();

3、查询数据

//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Get对象
Get get = new Get(Bytes.toBytes("laowang"));
//【可选】可以在这里指定要查询指定Rowkey数据哪些列族中的列
// 如果不指定,默认查询指定Rowkey所有列的内容
//get.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"));
//get.addColumn(Bytes.toBytes("info"),Bytes.toBytes("sex"));

Result result = table.get(get);
//如果不清楚HBase中到底有哪些列族和列,可以使用listCells()获取所有cell(单元格),cell对应的是某一个列的数据
List<Cell> cells = result.listCells();
for (Cell cell: cells) {
    //注意:下面获取的信息都是字节类型的,可以通过new String(bytes)转为字符串
    //列族
    byte[] famaily_bytes = CellUtil.cloneFamily(cell);
    //列
    byte[] column_bytes = CellUtil.cloneQualifier(cell);
    //值
    byte[] value_bytes = CellUtil.cloneValue(cell);
    System.out.println("列族:"+new String(famaily_bytes)+",列:"+new String(column_bytes)+",值:"+new String(value_bytes));
}
System.out.println("========================================================");
//如果明确知道HBase中有哪些列族和列,可以使用getValue(family, qualifier)直接获取指定列族中指定列的数据
byte[] age_bytes = result.getValue(Bytes.toBytes("info"),Bytes.toBytes("age"));
System.out.println("age列的值:"+new String(age_bytes));
//关闭table连接
table.close();

4、查询多版本数据

//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Get对象
Get get = new Get(Bytes.toBytes("laowang"));
//读取cell中的所有历史版本数据,不设置此配置的时候默认只读取最新版本的数据
//可以通过get.readVersions(2)来指定获取多少个历史版本的数据
get.readAllVersions();

Result result = table.get(get);

//获取指定列族中指定列的所有历史版本数据,前提是要设置get.readAllVersions()或者get.readVersions(2),否则只会获取最新数据
List<Cell> columnCells = result.getColumnCells(Bytes.toBytes("info"), Bytes.toBytes("age"));
for (Cell cell :columnCells) {
    byte[] value_bytes = CellUtil.cloneValue(cell);
    long timestamp = cell.getTimestamp();
    System.out.println("值为:"+new String(value_bytes)+",时间戳:"+timestamp);
}
//关闭table连接
table.close();

5、删除数据

//获取Table对象,指定要操作的表名,表需要提前创建好
Table table = conn.getTable(TableName.valueOf("student"));
//指定Rowkey,返回Delete对象
Delete delete = new Delete(Bytes.toBytes("laowang"));
//【可选】可以在这里指定要删除指定Rowkey数据哪些列族中的列
//delete.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"));

table.delete(delete);
//关闭table连接
table.close();

6、创建和删除表

想要操作表,也就是执行DDL操作,需要获取管理员权限,通过HBase获取

//获取管理权限,负责对HBase中的表进行操作(DDL操作)
Admin admin = conn.getAdmin();

(1)创建表

//指定列族信息
ColumnFamilyDescriptor familyDesc1 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info"))
        //在这里可以给列族设置一些属性
        .setMaxVersions(3)//指定最多存储多少个历史版本数据
        .build();
ColumnFamilyDescriptor familyDesc2 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("level"))
        //在这里可以给列族设置一些属性
        .setMaxVersions(2)//指定最多存储多少个历史版本数据
        .build();
ArrayList<ColumnFamilyDescriptor> familyList = new ArrayList<ColumnFamilyDescriptor>();
familyList.add(familyDesc1);
familyList.add(familyDesc2);

//获取TableDescriptor对象
TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf("test"))//指定表名
        .setColumnFamilies(familyList)//指定列族
        .build();
//创建表
admin.createTable(desc);

(2)删除表

//删除表,先禁用表
admin.disableTable(TableName.valueOf("test"));
admin.deleteTable(TableName.valueOf("test"));

五、最后对代码进行抽取,便于查看,完整代码如下

package com.imooc.hbase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 操作HBase
 * 表:创建、删除
 * 数据:增、删、改、查
 */
public class HBaseOp {
    public static void main(String[] args) throws Exception {
        //获取HBase数据库连接
        Connection conn = getConn();
        //添加数据
        //put(conn);

        //查询数据
        get(conn);

        /**
         * 查询多版本的数据
         * 当列的值有多个历史版本的时候
         *
         * 修改列族info的最大历史版本存储数量
         * alter 'student',{NAME=>'info',VERSIONS=>3}
         *
         * 然后再执行下面命令,向列族info中的age列中添加几次数据,实现多历史版本数据存储
         * put 'student','laowang','info:age','19'
         * put 'student','laowang','info:age','20'
         *
         */
        //getMoreVersion(conn);

        //修改数据--同添加数据

        //删除数据
        //delete(conn);

        //==============================分割线======================

        //获取管理权限,负责对HBase中的表进行操作(DDL操作)
        Admin admin = conn.getAdmin();
        //创建表
        //createTable(admin);

        //删除表
        //deleteTable(admin);

        //关闭admin连接
        admin.close();
        //关闭连接
        conn.close();

    }

    /**
     * 删除表
     * @param admin
     * @throws IOException
     */
    private static void deleteTable(Admin admin) throws IOException {
        //删除表,先禁用表
        admin.disableTable(TableName.valueOf("test"));
        admin.deleteTable(TableName.valueOf("test"));
    }

    /**
     * 创建表
     * @param admin
     * @throws IOException
     */
    private static void createTable(Admin admin) throws IOException {
        //指定列族信息
        ColumnFamilyDescriptor familyDesc1 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info"))
                //在这里可以给列族设置一些属性
                .setMaxVersions(3)//指定最多存储多少个历史版本数据
                .build();
        ColumnFamilyDescriptor familyDesc2 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("level"))
                //在这里可以给列族设置一些属性
                .setMaxVersions(2)//指定最多存储多少个历史版本数据
                .build();
        ArrayList<ColumnFamilyDescriptor> familyList = new ArrayList<ColumnFamilyDescriptor>();
        familyList.add(familyDesc1);
        familyList.add(familyDesc2);

        //获取TableDescriptor对象
        TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf("test"))//指定表名
                .setColumnFamilies(familyList)//指定列族
                .build();
        //创建表
        admin.createTable(desc);
    }

    /**
     * 删除数据
     * @param conn
     * @throws IOException
     */
    private static void delete(Connection conn) throws IOException {
        //获取Table,指定要操作的表名,表需要提前创建好
        Table table = conn.getTable(TableName.valueOf("student"));
        //指定Rowkey,返回Delete对象
        Delete delete = new Delete(Bytes.toBytes("laowang"));
        //【可选】可以在这里指定要删除指定Rowkey数据哪些列族中的列
        //delete.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"));

        table.delete(delete);
        //关闭table连接
        table.close();
    }

    /**
     * 查询多版本的数据
     * @param conn
     * @throws IOException
     */
    private static void getMoreVersion(Connection conn) throws IOException {
        //获取Table,指定要操作的表名,表需要提前创建好
        Table table = conn.getTable(TableName.valueOf("student"));
        //指定Rowkey,返回Get对象
        Get get = new Get(Bytes.toBytes("laowang"));
        //读取cell中的所有历史版本数据,不设置此配置的时候默认只读取最新版本的数据
        //可以通过get.readVersions(2)来指定获取多少个历史版本的数据
        get.readAllVersions();

        Result result = table.get(get);

        //获取指定列族中指定列的所有历史版本数据,前提是要设置get.readAllVersions()或者get.readVersions(2),否则只会获取最新数据
        List<Cell> columnCells = result.getColumnCells(Bytes.toBytes("info"), Bytes.toBytes("age"));
        for (Cell cell: columnCells) {
            byte[] value_bytes = CellUtil.cloneValue(cell);
            long timestamp = cell.getTimestamp();
            System.out.println("值为:"+new String(value_bytes)+",时间戳:"+timestamp);
        }
        //关闭table连接
        table.close();
    }

    /**
     * 查询数据
     * @param conn
     * @throws IOException
     */
    private static void get(Connection conn) throws IOException {
        //获取Table,指定要操作的表名,表需要提前创建好
        Table table = conn.getTable(TableName.valueOf("student"));
        //指定Rowkey,返回Get对象
        Get get = new Get(Bytes.toBytes("laowang"));
        //【可选】可以在这里指定要查询指定Rowkey数据哪些列族中的列
        //如果不指定,默认查询指定Rowkey所有列的内容
        get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"));
        get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("sex"));

        Result result = table.get(get);
        //如果不清楚HBase中到底有哪些列族和列,可以使用listCells()获取所有cell(单元格),cell对应的是某一列的数据
        List<Cell> cells = result.listCells();
        for (Cell cell : cells) {
            //注意:下面获取的信息都是字节类型的,可以通过new String(bytes)转为字符串
            //列族
            byte[] famaily_bytes = CellUtil.cloneFamily(cell);
            //列
            byte[] column_bytes = CellUtil.cloneQualifier(cell);
            //值
            byte[] value_bytes = CellUtil.cloneValue(cell);
            System.out.println("列族:"+new String(famaily_bytes)+",列:"+new String(column_bytes)+",值:"+new String(value_bytes));
        }
        System.out.println("==============================================");
        //如果明确知道HBase中有哪些列族和列,可以使用getValue(family,qualifier)直接获取指定列族中指定列的数据
        byte[] age_bytes = result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age"));
        System.out.println("age列的值:"+new String(age_bytes));
        //关闭table连接
        table.close();
    }

    /**
     * 添加数据
     *
     * @param conn
     * @throws IOException
     */
    private static void put(Connection conn) throws IOException {
        //获取Table,指定要操作的表名,表需要提前创建好
        Table table = conn.getTable(TableName.valueOf("student"));
        //指定Rowkey,返回put对象
        Put put = new Put(Bytes.toBytes("laowang"));
        //向put对象中指定列族、列、值
        //put 'student','laowang','info:age','18'
        put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("18"));
        //put 'student','laowang','info:sex','man'
        put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("sex"), Bytes.toBytes("man"));
        //put 'student','laowang','level:class','A'
        put.addColumn(Bytes.toBytes("level"), Bytes.toBytes("class"), Bytes.toBytes("A"));
        //向表中添加数据
        table.put(put);
        //关闭table连接
        table.close();
    }

    /**
     * 获取连接
     *
     * @return
     * @throws IOException
     */
    private static Connection getConn() throws IOException {
        //获取配置
        Configuration conf = HBaseConfiguration.create();
        //指定HBase使用的zk的地址,多个用逗号隔开
        conf.set("hbase.zookeeper.quorum", "bigdata01:2181");
        //指定HBase在hdfs上的根目录
        conf.set("hbase.rootdir", "hdfs://bigdata01:9000/hbase");
        //创建HBase连接,负责对HBase中的数据的一些增删改查(DML操作)
        return ConnectionFactory.createConnection(conf);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

做一个有趣的人Zz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值