当前位置: 首页 > news >正文

HBase API

我们之后的实际开发中不可能在服务器那边直接使用shell命令一直敲的,一般都是通过API进行操作的。

环境准备

新建Maven项目,导入Maven依赖

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

1、创建连接

        HBase 的客户端连接由 ConnectionFactory 类来创建(工厂模式直接创建),我们使用完之后需要手动关闭连接。同时连接 是一个重量级的,推荐一个进程使用一个连接,对 HBase 的命令通过连接中的两个属性 Admin 和 Table 来实现。其中 Admin 主要是针对元数据-表格的创建修改进行操作, Table 则是针对表格中数据的增加修改进行操作。

1.1、单线程创建连接

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.AsyncConnection;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.CompletableFuture;public class HBaseConnection {public static void main(String[] args) throws IOException {// 1. 创建连接配置参数Configuration conf = new Configuration();//对应我们 hbase-site.xml 中的配置信息的<name>和<value>的值conf.set("hbase.zookeeper.quorum","hadoop102,hadoop103,hadoop104");// 2. 创建连接// 默认使用同步连接Connection connection = ConnectionFactory.createConnection(conf);// 3. 使用连接System.out.println(connection);// 4. 关闭连接connection.close();}
}

1.2、多线程创建连接

我们真正开发中首先不会把配置参数写到代码中的,我们是通过Maven项目下的resources目录来读取配置文件来设置配置参数的,我们可以看源码:

Connection connection = ConnectionFactory.createConnection();

我们调用了工厂模式的 ConnectionFactory 的 createConnection 方法来创建连接,这里我们。

没有配置参数,因为HBase默认其实会自动帮我们添加配置参数:

我们可以看到当调用ConnectionFactory 的 createConnection 方法的时候,其实又调用了HBaseConfiguration 的 create 方法,

 

 该方法内部帮我们添加了配置参数:

可以看到,它其实是去读取我们Maven项目下的resources目录下的文件,所以我们需要将我们的配置参数写到resources目录下,最好使用 "hbase-ste.xml" 来命名,至于这个文件,我们直接复制我们hbase集群中conf目录下的hbase-site.xml 。 

其中,我们只需要留下关于我们zookeeper服务器连接地址的配置信息即可,别的全部删除,因为我们是客户端,我们不能设置服务端的配置,那些即使写了也不会生效。

 

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property><name>hbase.zookeeper.quorum</name><value>hadoop102,hadoop103,hadoop104</value><description>The directory shared by RegionServers.</description></property>
</configuration>

 使用类单例模式确保只使用一个连接,可以同时用于多个线程。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.AsyncConnection;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.CompletableFuture;public class HBaseConnection {// 声明一个静态属性public static Connection connection = null;static {// 1. 创建连接// 默认使用同步连接try {//使用读取本地配置文件的方式来添加参数connection = ConnectionFactory.createConnection();} catch (IOException e) {e.printStackTrace();}}public static void closeConnection() throws IOException {// 判断连接是否为 nullif (connection != null){connection.close();}}public static void main(String[] args) throws IOException {//使用多线程连接 直接使用创建好的连接 不再main线程单独创建System.out.println(HBaseConnection.connection);//在main线程的最后记得关闭连接HBaseConnection.closeConnection();}}

2、DDL

创建 HBaseDDL类,添加HBaseConnection的静态属性作为我们的连接对象,确保单例模式。

2.1、创建命名空间

我们上面说了,HBase中的 DDL 语句被封装到了 Admin中,所以我们需要先获取 Admin。

Admin admin = connection.getAdmin();

注意:在coding的过程中遇到异常不要老想着直接在方法名之后直接 throws ,这样虽然是简洁了一些,但是如果第一行抛出了一个IOException,之后几行再出现异常我们就察觉不到了,所以尽量在我们核心代码处try-catch,方便了解异常信息。

然后我们直接通过方法来创建 namespace ,这里的namespace是一个对象,这样做的原因是因为我们 HBase 的shell命令中创建namespace的时候就是不止一种方法,所以这里单纯字符串来创建namespace肯定不行,对象具有更完整属性。

第二种创建命名空间的方式中,我们可以看到有一个 键值对参数,这就需要设置我们对象的属性了。 

 

import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;import java.io.IOException;public class HBaseDDL {public static Connection connection = HBaseConnection.connection;/*** 创建命名空间* @param namespace 命名空间的名称*/public static void createNamespace(String namespace) throws IOException {// 1. 获取admin//admin是轻量级的 并且不是线程安全的 不推荐池化或者缓存这个连接//也就是说 用的时候再去获取 不用就把它关闭掉Admin admin = connection.getAdmin();// 2. 调用方法创建 namespace// 代码比shell更加底层 所以shell能实现的功能代码 一定也可以// 所以代码实现时 需要更完整的命名空间描述// 2.1 获取一个命名空间的建造者 => 设计师NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(namespace);// 2.2 给命名空间添加属性// 给namespace添加键值对属性其实并没有什么意义 只是给人注释一样builder.addConfiguration("user","lyh");// 2.3 使用builder构造出namespace对象// 创建命名空间造成的问题 属于方法本身的问题 不应该抛出try {admin.createNamespace(builder.build());} catch (IOException e) {System.out.println("该命名空间已经存在!");e.printStackTrace();}// 3. 关闭资源admin.close();}public static void main(String[] args) throws IOException {//测试创建马命名空间createNamespace("lyh");//记得关闭HBase连接HBaseConnection.closeConnection();}
}

运行结果 

 

2.2、判断表格是否存在

    /*** 判断表格是否存在* @param namespace 命名空间* @param tableName 表名* @return true-存在 false-不存在*/public static boolean isTableExists(String namespace,String tableName) throws IOException {// 1. 获取adminAdmin admin = connection.getAdmin();// 2. 使用方法判断表格是否存在boolean b = false;try {b = admin.tableExists(TableName.valueOf(namespace, tableName));} catch (IOException e) {e.printStackTrace();}// 3. 关闭adminadmin.close();// 4.返回结果return b;}

2.3、创建表

    /*** 创建表格* @param namespace 命名空间* @param tableName 表格名称* @param columnFamilies 列族名称 可以有多个*/public static void createTable(String namespace,String tableName,String... columnFamilies) throws IOException {// 判断是否有至少一个列族if (columnFamilies.length == 0){System.out.println("创建表格至少应该有一个列族");return;}// 判断表格是否已经存在if (isTableExists(namespace,tableName)){System.out.println("表格已经存在");return;}// 1. 获取adminAdmin admin = connection.getAdmin();// 2. 调用方法创建表格// 2.1 获取表格的建造者TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(TableName.valueOf(namespace,tableName));// 2.2 添加参数for (String columnFamily : columnFamilies) {// 2.3 获取列族建造者ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(columnFamily));// 2.4 通过建造者创建对应列族描述// 添加版本参数-维护的版本数columnFamilyDescriptorBuilder.setMaxVersions(5);// 2.5 创建添加完参数的列族描述builder.setColumnFamily(columnFamilyDescriptorBuilder.build());}// 2.3 创建表格描述try {admin.createTable(builder.build());} catch (IOException e) {//System.out.println("表格已经存在");e.printStackTrace();}// 2.4 关闭adminadmin.close();}

2.4、修改表

这里需要注意的比较多:

我们这里修改表格的列族版本,首先就需要获取表格描述和列族描述,但是我们不能重新通过newBuilder创建这两种描述,而是应该使用旧的描述。

对于旧的表格描述来说,我们可以通过admin的getDescriptor()来获取旧的描述。

对于旧的列族描述来说,我们可以通过表格描述对象的getColumnFamily()方法来获取。

    /*** 修改表格中一个列族的版本* @param namespace 命名空间* @param tableName 表名* @param columnFamily 列族* @param version 维护的版本*/public static void modifyTable(String namespace,String tableName,String columnFamily,int version) throws IOException {// 判断表格是否存在if (!isTableExists(namespace,tableName)){System.out.println("表格不存在");return;}// 1. 获取adminAdmin admin = connection.getAdmin();// 2. 调用方法修改表格// 2.0 获取之前的表格描述TableDescriptor tableDescriptor = null;try {tableDescriptor = admin.getDescriptor(TableName.valueOf(namespace, tableName));} catch (IOException e) {System.out.println("表格不存在");e.printStackTrace();}// 2.1 创建一个表格描述建造者// 如果使用填写 tableName 的方法 相当于创建了一个新的表格描述 没有之前的信息// 如果想要修改表格的信息 必须调用方法填写一个旧的表格描述TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableDescriptor);// 2.2 对应建造者进行表格数据的修改// 获取旧的列族描述ColumnFamilyDescriptor columnFamily1 = tableDescriptor.getColumnFamily(Bytes.toBytes(columnFamily));// 创建列族描述建造者ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(columnFamily1);// 修改对应的版本columnFamilyDescriptorBuilder.setMaxVersions(version);// 在这里修改的时候 如果填写的是新创建的列族描述 那么我们表格之前的其它属性会被初始化 所以要使用旧的列族描述builder.modifyColumnFamily(columnFamilyDescriptorBuilder.build());try {admin.modifyTable(builder.build());} catch (IOException e) {e.printStackTrace();}// 3. 关闭adminadmin.close();}

 

2.5、删除表

需要注意HBase中删除表前必须标记表为不可用!

/*** 删除表格* @param namespace 命名空间* @param tableName 表名* @return true-删除成功*/public static boolean deleteTable(String namespace,String tableName) throws IOException {// 1. 判断表格是否存在if (!isTableExists(namespace,tableName)){System.out.println("表格不存在 无法删除");return false;}// 2. 获取adminAdmin admin = connection.getAdmin();// 3. 调用相关的方法删除表格try {// hbase 删除表格前必须标记标记表格为不可用才能删除admin.disableTable(TableName.valueOf(namespace,tableName));admin.deleteTable(TableName.valueOf(namespace,tableName));} catch (IOException e) {e.printStackTrace();}// 4. 关闭adminadmin.close();return true;}

3、DML

3.1、插入数据

我们可以看到,插入数据的put方法中要求参数必须为Byte类型,这也应证了我们之前第一篇博客说的-HBase的Cell的数据都是以Byte字节类型存储的。

public class HBaseDML {//静态属性public static Connection connection = HBaseConnection.connection;/*** 插入数据* @param namespace 命名空间* @param tableName 表名* @param rowKey 行键* @param columnFamily 列族* @param columnName 列名* @param value 值*/public static void putCell(String namespace,String tableName,String rowKey,String columnFamily,String columnName,String value) throws IOException {// 1. 获取 TableTable table = connection.getTable(TableName.valueOf(namespace,tableName));// 2. 调用相关方法实现数据插入// 2.1 创建 put 对象Put put = new Put(Bytes.toBytes(rowKey));// 2.2 给 put 对象添加属性put.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(columnName),Bytes.toBytes(value));// 2.3 将对象写入对应的方法try {table.put(put);} catch (IOException e) {e.printStackTrace();}// 3. 关闭tabletable.close();}public static void main(String[] args) throws IOException {// 测试插入数据putCell("bigdata","student","1005","info","name","hbase");System.out.println("其他代码");// 关闭连接HBaseConnection.closeConnection();}
}

3.2、查询数据

未完待续

3.3、扫描数据

3.4、带过率扫描

3.5、删除数据

相关文章:

HBase API

我们之后的实际开发中不可能在服务器那边直接使用shell命令一直敲的&#xff0c;一般都是通过API进行操作的。 环境准备 新建Maven项目&#xff0c;导入Maven依赖 <dependencies><dependency><groupId>org.apache.hbase</groupId><artifactId>…...

Qt6之QListWidget——Qt仿ToDesk侧边栏(1)

一、 QLitWidget概述 注意&#xff1a;本文不是简单翻译Qt文档或者接口函数&#xff0c;而侧重于无代码Qt设计器下演示使用。 QListWidget也称列表框类&#xff0c;它提供了一个类似于QListView提供的列表视图&#xff0c;但是它具有一个用于添加和删除项的经典的基于项的接口…...

Prometheus技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》

一、查看可安装的版本 docker search prom/prometheus 二、拉取镜像 docker pull prom/prometheus 三、查看镜像 docker images 四、书写配置文件-以及创建挂载目录 宿主机挂载目录位置&#xff1a; 以及准备对应的挂载目录&#xff1a; /usr/local/docker/promethues/se…...

Android 数据库之GreenDAO

GreenDAO 是一款开源的面向 Android 的轻便、快捷的 ORM 框架&#xff0c;将 Java 对象映射到 SQLite 数据库中&#xff0c;我们操作数据库的时候&#xff0c;不再需要编写复杂的 SQL语句&#xff0c; 在性能方面&#xff0c;greenDAO 针对 Android 进行了高度优化&#xff0c;…...

kotlin 编写一个简单的天气预报app(六)使用recyclerView显示forecast内容

要使用RecyclerView显示天气预报的内容 先在grandle里添加recyclerView的引用 implementation androidx.recyclerview:recyclerview:1.3.1创建一个RecyclerView控件&#xff1a;在布局文件中&#xff0c;添加一个RecyclerView控件&#xff0c;用于显示天气预报的列表。 这是一…...

jpa Page 1 of 0 containing UNKNOWN instances错误关于like问题的解决记录

导致这个问题的原因很多&#xff0c;这里记录一下我碰到的问题和解决方法。 网上有说时 pageNo要从0开始&#xff0c;我的不是这个问题。 在使用springboot jpa时&#xff0c;发现使用 t.ip like %?5% 语句&#xff0c;如果数据库记录的ip is null时&#xff0c;将查询不到该…...

Python实战之使用Python进行数据挖掘详解

一、Python数据挖掘 1.1 数据挖掘是什么&#xff1f; 数据挖掘是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;通过算法&#xff0c;找出其中的规律、知识、信息的过程。Python作为一门广泛应用的编程语言&#xff0c;拥有丰富的数据挖掘库&#…...

scala 加载properties文件

利用java.util.Properties加载 import java.io.FileInputStream import java.util.Properties object LoadParameter {//动态获取properties文件可配置参数val props new Properties()def getParameter(s:String,filePath:String): String {props.load(new FileInputStream(f…...

备战秋招012(20230808)

文章目录 前言一、今天学习了什么&#xff1f;二、动态规划1.概念2.题目 总结 前言 提示&#xff1a;这里为每天自己的学习内容心情总结&#xff1b; Learn By Doing&#xff0c;Now or Never&#xff0c;Writing is organized thinking. 提示&#xff1a;以下是本篇文章正文…...

QT中定时器的使用

文章目录 概述步骤 概述 Qt中使用定时器大致有两种&#xff0c;本篇暂时仅描述使用QTimer实现定时器 步骤 // 1.创建定时器对象 QTimer *timer new QTimer(this);// 2.开启一个定时器&#xff0c;5秒触发一次 timer->start(5000); // 3.建立信号槽连接&am…...

【UE4】多人联机教程(重点笔记)

效果 1. 创建房间、搜索房间功能 2. 根据指定IP和端口加入游戏 步骤 1. 新建一个第三人称角色模板工程 2. 创建一个空白关卡&#xff0c;这里命名为“InitMap” 3. 新建一个控件蓝图&#xff0c;这里命名为“UMG_ConnectMenu” 在关卡蓝图中显示该控件蓝图 打开“UMG_Connec…...

【go】GIN参数重复绑定报错EOF问题

文章目录 1 问题描述2 解决&#xff1a;替换为ShouldBindBodyWith 1 问题描述 在 Gin 框架中&#xff0c;当多次调用 ShouldBind() 或 ShouldBindJSON() 方法时&#xff0c;会导致请求体的数据流被读取多次&#xff0c;从而出现 “EOF” 错误。 例如在api层绑定了参数&#x…...

关于MySQL中的binlog

介绍 undo log 和 redo log是由Inno DB存储引擎生成的。 在MySQL服务器架构中&#xff0c;分为三层&#xff1a;连接层、服务层&#xff08;server层&#xff09;、执行层&#xff08;存储引擎层&#xff09; bin log 是 binary log的缩写&#xff0c;即二进制日志。 MySQL…...

我维护电脑的方法

无论是学习还是工作&#xff0c;电脑都是IT人必不可少的重要武器&#xff0c;一台好电脑除了自身配置要经得起考验&#xff0c;后期主人对它的维护也是决定它寿命的重要因素&#xff01; 你日常是怎么维护你的“战友”的呢&#xff0c;维护电脑运行你有什么好的建议吗&#xff…...

AP51656 电流采样降压恒流驱动IC RGB PWM深度调光 LED电源驱动

产品描述 AP51656是一款连续电感电流导通模式的降压恒流源&#xff0c;用于驱动一颗或多颗串联LED 输入电压范围从 5 V 到 60V&#xff0c;输出电流 可达 1.5A 。根据不同的输入电压和 外部器件&#xff0c; 可以驱动高达数十瓦的 LED。 内置功率开关&#xff0c;采用电流采样…...

Python爬虫的解析(学习于b站尚硅谷)

目录 一、xpath  1.xpath插件的安装  2. xpath的基本使用  &#xff08;1&#xff09;xpath的使用方法与基本语法&#xff08;路径查询、谓词查询、内容查询&#xff08;使用text查看标签内容&#xff09;、属性查询、模糊查询、逻辑运算&#xff09;  &#xff08;2&a…...

python的virtualenv虚拟环境无法激活activate

目录 问题描述&#xff1a; 解决办法&#xff1a; 解决结果&#xff1a; 问题描述&#xff1a; PS D:\pythonProject\pythonProject\DisplayToolLibs\venv\Scripts> .\activate .\activate : 无法加载文件 D:\pythonProject\pythonProject\DisplayToolLibs\venv\Scripts\…...

uniapp中token操作:存储、获取、失效处理。

实现代码 存储token:uni.setStorageSync(token, res.data.result);获取token:uni.getStorageSync(token);清除token&#xff1a;uni.setStorageSync(token, ); 应用场景 在登录操作中&#xff0c;保存token pwdLogin() {....this.$axios.request({url: .....,method: post,p…...

乐鑫科技 2022 笔试面试题

岗位:嵌入式软件实习生。 个人情况:本科双非电子信息工程,硕士华五软件工程研一在读;本科做过一些很水的项目 ,也拿项目搞了一些奖,相对来说嵌入式方向比较对口。 时间线及面试流程 2021.04.02 笔试 题目分为选择题和编程题,选择题二十题,编程题两题; 选择题基本…...

实现UDP可靠性传输

文章目录 1、TCP协议介绍1.1、ARQ协议1.2、停等式1.3、回退n帧1.4、选择性重传 1、TCP协议介绍 TCP协议是基于IP协议&#xff0c;面向连接&#xff0c;可靠基于字节流的传输层协议 1、基于IP协议&#xff1a;TCP协议是基于IP协议之上传输的&#xff0c;TCP协议报文中的源端口IP…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...