Java远程连接+CRUD Ubuntu下HBase(增删改查)

作业一:Java远程连接+CRUD Ubuntu下HBase

一. 准备工作以及使用工具

注:因为习惯原因,本次实验使用idea工具完成,这个文章也给想使用idea工具去完成作业的同学一个参考。

  1. ​ idea编辑工具
  2. ​ maven项目管理和构建自动化工具
  3. ​ java1.8
  4. ​ 部署好的Ubuntu虚拟机和配置好的Hbase
  5. ​ FinalShell 远程连接虚拟机工具

二.作业步骤

1.配置window的hosts。

​ 将Ubuntu虚拟机的ip设置为静态ip,使用 ifconfig 命令进行查看,其中192.168.88.131就是ip地址,找到windows目录下的hosts文件存放地址 C:\Windows\System32\drivers\etc 将静态ip和代表域名写入保存。

ifconfig

在这里插入图片描述

在这里插入图片描述

2. 使用idea创建maven项目,并做好相关配置。
2.1 创建maven项目。

​ 选择好直接保存的路径,方便管理,项目名称取为work1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 编写maven的pom.xml文件。

​ 使用坐标导入仓库的bhase相关依赖,只需要这样,maven仓库就会自己自动下载bhase API的相关jar包,由于我们还需要使用测试,所以我们要导入junit 和 log4j坐标备用。

<dependencies>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>2.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>2.3.5</version>
        </dependency>


        <!-- Log4j2的依赖 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.2</version>
        </dependency>`在这里插入代码片`

        <!-- Junit依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.3 编写java代码使用 hbase API 连接hbase的代码
2.3.1HbaseConnection.java

注:因为老师截图代码好像因为版本古老,里面的一些API也已经被删除了,所以我写的代码与老师写的会有一些差异,,但是大体功能是一样的。

​ 在连接方法上,我使用了static 单例连接,代码如下。也就是在HbaseConnection 可以被直接使用,不用new,在HbaseConnection被使用时,connection就会开始和虚拟机的hbase连接 。

public class HbaseConnection {

    public static Connection connection = null;

    // 静态的连接
    static {

        try {
            connection = ConnectionFactory.createConnection();
            System.out.println("数据库连接成功");
        } catch (IOException e) {
            System.out.println("数据库连接失败");
            e.printStackTrace();
        }
    }


    // 关闭连接
    public static void closeConnection() throws IOException {
        // 判断连接是否为null
        if (connection != null){
            connection.close();
        }
    }
    
}

大家会发现这个代码和老师的有太多地方不一样了:configuration在哪去了,没有配置项如何建立连接?

        configuration = HBaseConfiguration.create();
        configuration.set("hbase.zookeeper.quorum", "node1");

​ 这个需要翻看文档和看源码来理解,我在这简单说一下:在这个方法connection = ConnectionFactory.createConnection();使用时,其实还要又有这个方法,它的内部,HBaseConfiguration被重载了,慢慢往下找,就会发现他最终会去work1项目文件下的 resources资源目录,我们只要将,hbase-site.xml等相关配置项复制过来就可以了。

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

2.3.2 HBaseCRUD.java

​ 这个java类,通过HbaseConnection.java连接 hbase 后,完成相关的CRUD操作,也就是数据库的增删改查。我改了一些写法,但是大体没有动,但在写代码时,idea 提示很多的API已经弃用了,虽然还可以跑起来,但是官方是不推荐的。

​ 这块代码没有什么好说的,他的逻辑是很接近 hbase shell 的,我们要分清楚的还是Hbase数据库的结构,也就是,表(table),行键(Row Key),列族(columnFamilies),时间戳(Timestamp)。

package org.example;

import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

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

/**
 * HBaseCRUD类提供了对HBase数据库进行创建、读取、更新和删除操作的方法。
 */
public class HBaseCRUD {
    public Connection hbaseConnection;
    public Admin admin;
    TableName tableName;
    HTableDescriptor tableDescriptor;
    HColumnDescriptor hColumnDescriptor;
    Table table;

    /**
     * HBaseCRUD构造函数,初始化HBase连接和管理员对象。
     */
    public HBaseCRUD(){
        hbaseConnection =  HbaseConnection.connection;
        getAdmin();
    }

    /**
     * 获取HBase管理员对象。
     */
    public void getAdmin(){
        try {
            admin = hbaseConnection.getAdmin();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据表名获取表对象。
     * 
     * @param name 表的名称。
     * @return 返回对应的Table对象。
     * @throws IOException 如果发生IO异常。
     */
    public Table getTable(String name) throws IOException {
        table = hbaseConnection.getTable(TableName.valueOf(name));
        return table;
    }

    /**
     * 创建新表。
     * 
     * @param name 表的名称。
     * @param columnFamilies 列族数组。
     * @throws IOException 如果发生IO异常。
     */
    public void createTable(String name, String[] columnFamilies) throws IOException {
        tableName = TableName.valueOf(name);
        if (admin.tableExists(tableName)){
            admin.disableTable(tableName);
            admin.deleteTable(tableName);
            System.out.println(tableName.toString() + "is exists is deleted");
        }
        tableDescriptor = new HTableDescriptor(tableName);
        for(String columnFamily : columnFamilies){
            hColumnDescriptor = new HColumnDescriptor(columnFamily);
            tableDescriptor.addFamily(hColumnDescriptor);
        }
        admin.createTable(tableDescriptor);
        System.out.println("Table is created");
    }

    /**
     * 向表中插入或修改数据。
     * 
     * @param name 表的名称。
     * @param rowKey 行键。
     * @param columnFamily 列族。
     * @param columnName 列名。
     * @param timeStamp 时间戳。
     * @param value 要插入或修改的值。
     * @throws IOException 如果发生IO异常。
     */
    public void insertAndModify(String name, String rowKey, String columnFamily,
                                String columnName, Long timeStamp, String value) throws IOException {

        getTable(name);
        Put put = new Put(Bytes.toBytes(rowKey));
        put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName), timeStamp, Bytes.toBytes(value));

        table.put(put);
        table.close();
    }

    /**
     * 根据行键和列名获取特定单元格的值。
     * 
     * @param name 表的名称。
     * @param rowKey 行键。
     * @param columnFamily 列族。
     * @param columnName 列名。
     * @throws IOException 如果发生IO异常。
     */
    public void selectByGet(String name, String rowKey, String columnFamily, String columnName) throws IOException {

        Get get = new Get(Bytes.toBytes(rowKey));

        Result result = getTable(name).get(get);

        byte[] value = result.getValue(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName));
        System.out.println("Value = " +  Bytes.toString(value));
    }

    /**
     * 根据行键、列族和列名,以及最大版本数获取单元格的值。
     * 
     * @param name 表的名称。
     * @param rowKey 行键。
     * @param columnFamily 列族。
     * @param columnName 列名。
     * @param maxVersion 最大版本数。
     * @throws IOException 如果发生IO异常。
     */
    public void selectBycell(String name, String rowKey, String columnFamily, String columnName,int maxVersion) throws IOException {
        Get get = new Get(Bytes.toBytes(rowKey));
        try {
            get.setMaxVersions(maxVersion);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        Result result = getTable(name).get(get);
        List<Cell> cells = result.getColumnCells(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName));

        for(Cell cell : cells){
            byte[] cvalue = CellUtil.cloneValue(cell);
            System.out.println("Value = " +  Bytes.toString(cvalue));
        }
    }

    /**
     * 根据行键获取整行数据。
     * 
     * @param name 表的名称。
     * @param rowKey 行键。
     * @throws IOException 如果发生IO异常。
     */
    public void selectByRow(String name, String rowKey) throws IOException {
        Get get = new Get(Bytes.toBytes(rowKey));
        Result result = getTable(name).get(get);
        for(Cell cell : result.rawCells()){
            System.out.println("Row = " +  Bytes.toString(CellUtil.cloneRow(cell)));
            System.out.println("Family = " +  Bytes.toString(CellUtil.cloneFamily(cell)));
            System.out.println("Column = " +  Bytes.toString(CellUtil.cloneQualifier(cell)));
            System.out.println("Value = " +  Bytes.toString(CellUtil.cloneValue(cell)));
            System.out.println("Timestamp = " +  cell.getTimestamp());
            System.out.println("----------------------------------------");
        }
    }

    
    /**
     * 清空表中的所有数据。
     * 
     * @param name 表的名称。
     */
    public void truncateTable(String name)  {
        getAdmin();

        TableName tableName = TableName.valueOf(name);
        try {
            admin.disableTable(tableName);
            admin.truncateTable(tableName, false);
        } catch (IOException e) {
            System.out.println("清空表数据失败");
            throw new RuntimeException(e);
        }
        System.out.println("清空表数据成功");
    }
    
     /**
     * 删除指定命名空间下的表格。
     *
     * @param tableName 表格的名称。
     * @throws IOException 如果在删除过程中遇到IO异常。
     */
    public  void deleteTable(String tableName) throws IOException {
        // 1. 建立连接
        getAdmin();
        
        // 2. 调用方法删除表格
        TableName tableName1 = TableName.valueOf(tableName);
        if (admin.tableExists(tableName1)) {
            admin.disableTable(tableName1);
            admin.deleteTable(tableName1);
            System.out.println("Table " + tableName + " is deleted.");
        }else System.out.println("Table " + tableName + " does not exist.");

    }

}

2.3.3 HbaseTest.java

​ 最后这个,和前面创建的类不一样,这是一个测试类,我们在之前创建项目时看见,项目除了有main.java还有个test.java,这个test.java 是专门用来测试的,我们要将HbaseTest.java放在 test.java下面。

​ 我们知道,java代码想要run起来必须要有**main**函数,一个两个测试还好,测试项目多起来,通过main,就会特别麻烦,main会越来越多,或者main里面的代码,注释掉的代码也会越来越多。所以我们要用junit这个包来完成简单的测试。

​ 他的使用方法很简单,在我们写好的方法头上加上 @Test 就可以单独运行这个方法了

在这里插入图片描述

import org.example.HBaseCRUD;
import org.junit.Test;

import java.io.IOException;

/**
 * HbaseTest 类用于通过 JUnit 测试 HBase 数据库的 CRUD(创建、读取、更新、删除)操作。
 */
public class HbaseTest {
    // HBase 表名称
    String name = "kpl";
    // 行键
    String rowkey = "0001";
    // 列族名称
    String columnfamily = "role";
    // 属性名称
    String attr_name = "name";
    String attr_type = "type";
    String attr_duty = "duty";
    // 属性值
    String value_name = "Hanxin";
    String value_type = "Warrior";
    String value_duty = "Wild";
    // 列族名称数组
    String[] familyNames = {"role", "attack", "defence"};
    // 时间戳
    long timeStamp = 5;

    /**
     * 测试创建 HBase 表。
     * @throws IOException 如果创建表时发生 I/O 错误。
     */
    @Test
    public void testCreateHbase(){
        HBaseCRUD hBaseCRUD = new HBaseCRUD();
        try {
            hBaseCRUD.createTable(name, familyNames);
        } catch (IOException e) {
            System.out.println("创建表失败");
            throw new RuntimeException(e);
        }
    }

    /**
     * 测试向 HBase 表中插入数据。
     * @throws IOException 如果插入数据时发生 I/O 错误。
     */
    @Test
    public void testInsertHbase(){
        HBaseCRUD hBaseCRUD = new HBaseCRUD();
        try {
            // 插入属性值
            hBaseCRUD.insertAndModify(name, rowkey, columnfamily, attr_name, timeStamp, value_name);
            hBaseCRUD.insertAndModify(name, rowkey, columnfamily, attr_type, timeStamp, value_type);
            hBaseCRUD.insertAndModify(name, rowkey, columnfamily, attr_duty, timeStamp, value_duty);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("插入数据成功");
    }

    /**
     * 测试通过 Get 和 Row 键选择数据。
     * @throws IOException 如果选择数据时发生 I/O 错误。
     */
    @Test
    public void testSelectByGet(){
        HBaseCRUD hBaseCRUD = new HBaseCRUD();
        try {
            // 通过 Get 方式选择数据
            hBaseCRUD.selectByGet(name, rowkey, columnfamily, attr_name);
            // 通过 Row 键选择数据
            hBaseCRUD.selectByRow(name, rowkey);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 测试清空 HBase 表数据。
     */
    @Test
    public void testTuncateHbase(){
        HBaseCRUD hBaseCRUD = new HBaseCRUD();
        hBaseCRUD.truncateTable(name);
    }
    
     /**
     * 测试删除 HBase 表数据。
     */
    @Test
    public void testdeleteHbase() throws IOException {
        HBaseCRUD hBaseCRUD = new HBaseCRUD();
        hBaseCRUD.deleteTable(name);
    }

}

三.代码测试

  1. 使用FinalShell 远程连接 Ubuntu 启动hbase,查看jps。

在这里插入图片描述

  1. 没有问题后,启动hbase shell,使用list命令查看 hbase中的表。这时候还是什么都没有。

在这里插入图片描述

  1. 使用HbaseTest.java中的 testCreateHbase方法先测试连接hbase并创建表“kpl”。运行成功后再看hbase shell 使用 list 查看,“kpl”也是创建成功了。

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

  1. 接下来就是测试 testInsertHbase方法,往“kpl”表里面插入准备好的数据,也一样成功了。

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

  1. 测试 testSelectByGet方法 ,通过Get 和 Row 键查询数据,也是没有问题。

    在这里插入图片描述

  2. testTuncateHbase方法他是要来清除表中数据的。运行后,scan “kpl”,里面就没有数据了

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

  1. 最后一个 testdeleteHbase删除表,运行成功后, “kpl”表也就被删除了。
    在这里插入图片描述

在这里插入图片描述

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值