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

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

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

​ idea编辑工具​ maven项目管理和构建自动化工具​ java1.8​ 部署好的Ubuntu虚拟机和配置好的Hbase​ 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坐标备用。

org.apache.hbase

hbase-client

2.3.5

org.apache.hbase

hbase-server

2.3.5

org.apache.logging.log4j

log4j-core

2.17.2

`在这里插入代码片`

junit

junit

4.12

test

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 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);

}

}

三.代码测试

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

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

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

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

测试 testSelectByGet方法 ,通过Get 和 Row 键查询数据,也是没有问题。 testTuncateHbase方法他是要来清除表中数据的。运行后,scan “kpl”,里面就没有数据了

最后一个 testdeleteHbase删除表,运行成功后, “kpl”表也就被删除了。

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: