目录
复制Hadoop的配置文件core-site.xml和HBase的配置文件hbase-site.xml到resources目录中
某自来水公司,需要存储大量的缴费明细数据,以下截取了缴费明细的一部分内容:
| 用户id | 姓名 | 地址 | 性别 | 缴费时间 | 表示数(本次) | 表示数(上次) | 用量(立方) | 合计金额 | 查表日期 | 最迟缴费日期 |
| 4944191 | 张三 | 河北省石家庄市裕华区万达校区2-1-401 | 男 | 2022-3-27 | 308.1 | 283.1 | 25 | 150 | 2022-2-25 | 2022-4-24 |
因为缴费明细的数据记录非常庞大,该公司的信息部门决定使用hbase来存储这些数据,并且可以使用java来访问这些数据。
idea:社区版免费,企业版收费
eclipse:开源免费







先导出到本地计算机



再添加一个日志log4j的配置文件



这个是一个小测试,来测试环境,下面那个才是真正的连接器
package cn.edu.hgu.dashuju19.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import java.io.IOException;
/**
* @description: 创建hbase的连接及管理对象
* @author:
* @date: 2022-3-28
*/
public class HbaseConnect {
public static void main(String[] args){
//1、创建hbase的配置
Configuration configuration = new Configuration();
//2、创建hbase的连接
Connection connection;
{
try {
connection = ConnectionFactory.createConnection(configuration);
System.out.println(connection);
//3、创建admin对象
Admin admin = connection.getAdmin();
System.out.println(admin);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

package cn.edu.hgu.dashuju19.hbase;
import org.apache.hadoop.conf.Configuration;
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;
/**
* Hbase_connect
* @author
* @date 2022-03-30 11:58
*/
public class HbaseConnect {
private static Connection connection;
private static Admin admin;
public static void main(String[] args) throws IOException {
// 1. 使用HbaseConfiguration.create()创建Hbase配置
Configuration configuration = HBaseConfiguration.create();
// 2. 使用ConnectionFactory.createConnection()创建Hbase连接
connection = ConnectionFactory.createConnection(configuration);
// 3. 要创建表,需要基于Hbase连接获取admin管理对象
// 要创建表、删除表需要和HMaster连接,所以需要有一个admin对象
admin = connection.getAdmin();
TableName tableName = TableName.valueOf("WATER_BILL2");
// 4. 判断表是否存在
if(admin.tableExists(tableName)) {
// a) 存在,则退出
return;
}
// 构建表
// 5. 使用TableDescriptorBuilder.newBuilder构建表描述构建器
// TableDescriptor: 表描述器,描述这个表有几个列蔟、其他的属性都是在这里可以配置
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);
// 6. 使用ColumnFamilyDescriptorBuilder.newBuilder构建列蔟描述构建器
// 创建列蔟也需要有列蔟的描述器,需要用一个构建起来构建ColumnFamilyDescriptor
// 经常会使用到一个工具类:Bytes(hbase包下的Bytes工具类)
// 这个工具类可以将字符串、long、double类型转换成byte[]数组
// 也可以将byte[]数组转换为指定类型
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("C1"));
// 7. 构建列蔟描述,构建表描述
ColumnFamilyDescriptor cfDes = columnFamilyDescriptorBuilder.build();
// 建立表和列蔟的关联
tableDescriptorBuilder.setColumnFamily(cfDes);
TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
// 8. 创建表
admin.createTable(tableDescriptor);
// 9. 使用admin.close、connection.close关闭连接
admin.close();
connection.close();
}
}

这下准备工作就做好了
接下来就是八个案例了
还是那句话,需要源码包的私信我,当然这里面也有源码可以复制
这几个案例放在一个java文件里了
源码放在这里
大家在做案例的时候需要根据介绍来打开或者取消注释
package cn.edu.hgu.dashuju19.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CompareOperator;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.List;
/**
* @description 创建hbase的连接以及管理对象
* @date 2022-3-30
*/
public class HbaseJavaAPIMain {
public static void main(String[] args) throws IOException {
Admin admin = getAdmin();
// //调用删除表的方法
// boolean result = deleteTable(admin, "WATER_BILL");
// if (result) {
// System.out.println("删除成功");
// }else {
// System.out.println("表不存在");
// }
//
//
// 调用插入数据的方法
// putTable(admin.getConnection(),"water_bill","4944191","info","addr","石家庄市裕华区");
// //获取name值
// String name = getValue(admin.getConnection(),"water_bill","4944191","info","name");
// System.out.println(name);
// //输出rowkey
// getOne(admin.getConnection(),"water_bill","4944191");
删除某行数据
// deleteOne(admin.getConnection(),"water_bill","4944191");
// //查询六月份数据
queryDate(admin.getConnection(), "WATER_BILL","C1","RECORD_DATE","2020-06-01", "2020-06-30");
// // 关闭admin
// admin.close();
}
/**
* 获取admin对象
*
* @return
* @throws IOException
*/
public static Admin getAdmin() throws IOException {
//1.创建hbase的配置
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorom", "192.168.153.100");
configuration.set("hbase.zookeeper.property.clientPort", "2181");
configuration.set("hbase.master", "192.168.153.100:16010");
//2.创建hbase连接
Connection connection = null;
Admin admin = null;
try {
//通过工厂模式,根据配置来创建连接
connection = ConnectionFactory.createConnection(configuration);
System.out.println(connection);
//3.创建admin对象
admin = connection.getAdmin();
} catch (IOException e) {
e.printStackTrace();
}
return admin;
}
/**
* 删除表
*
* @param admin
* @param name
* @throws IOException
* @return
*/
public static boolean deleteTable(Admin admin, String name) throws IOException {
//定义表名
TableName tableName = TableName.valueOf(name);
//判断表是否存在
if (admin.tableExists(tableName)) {
//禁用表名
admin.disableTable(tableName);
//删除表
admin.deleteTable(tableName);
return true;
} else {
return false;
}
}
/**
* 往表中插入数据
* @param connection
* @param tableName
* @param rowkey
* @param columnFamily
* @param column
* @param value
* @throws IOException
*/
public static void putTable(Connection connection,String tableName,String rowkey,String columnFamily,String column,String value) throws IOException {
//获取table对象
Table table = connection.getTable(TableName.valueOf(tableName));
//根据rowkey获取put对象
Put put = new Put(Bytes.toBytes(rowkey));
//添加姓名列
put.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(column),Bytes.toBytes(value));
//插入数据
table.put(put);
//关闭table
table.close();
}
/**
* 获取某列的值
* @param connection
* @param tableName
* @param rowkey
* @param columnFamily
* @param column
* @return
* @throws IOException
*/
public static String getValue(Connection connection, String tableName, String rowkey, String columnFamily, String column) throws IOException {
//1.获取htable
Table table = connection.getTable(TableName.valueOf(tableName));
//2.使用rowkey构建get对象
Get get = new Get(Bytes.toBytes(rowkey));
//3.执行get请求。获取result对象
Result result = table.get(get);//result对象创建快捷键ctrl+alt+v
//4.某列的值
String name = Bytes.toString(result.getValue(columnFamily.getBytes(),column.getBytes()));
//System.out.println(name);
//System.out.println(result.toString());
// byte[] row = result.getRow();
//5.关闭表
table.close();
return name;
// System.out.println("rowkey=>" + Bytes.toString(row));
//获取所有单元格
//List<Cell> cells = result.listCells();
}
/**
* 获取并显示某行的数据
*/
public static void getOne(Connection connection,String tableName,String rowkey) throws IOException {
//1.获取htable
Table table = connection.getTable(TableName.valueOf(tableName));
//2.使用rowkey构建get对象
Get get = new Get(Bytes.toBytes(rowkey));
//3.执行get请求。获取result对象
Result result = table.get(get);//result对象创建快捷键ctrl+alt+v
//4.获取rowkey
byte[] row = result.getRow();
System.out.println("rowkey=>" + Bytes.toString(row));
//5.获取所有的单元格
List<Cell> cells = result.listCells();
//6.迭代处理每个单元格
for (Cell cell:cells) {
System.out.print(Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength()));
System.out.println("=>" + Bytes.toString(cell.getValueArray(),cell.getValueOffset(),cell.getValueLength()));
}
//7.关闭表
table.close();
}
/**
* 删除指定行
*/
public static void deleteOne(Connection connection,String tableName,String rowkey) throws IOException {
//1.获取htable
Table table = connection.getTable(TableName.valueOf(tableName));
//2.使用rowkey构建delete对象
Delete delete = new Delete(Bytes.toBytes(rowkey));
//3.执行delete请求
table.delete(delete);
//4.关闭表
table.close();
}
/**
* 查询某列某个日期范围的数据
* @param connection
* @param tableName
* @param columnFamily
* @param column
* @param startValue
* @param endValue
* @throws IOException
*/
public static void queryDate(Connection connection,String tableName,String columnFamily,String column,String startValue,String endValue) throws IOException {
//1.获取htable
Table table = connection.getTable(TableName.valueOf(tableName));
//2.构建scan对象
Scan scan = new Scan();
//3.构建两个过滤器
//构建日期范围的过滤器
//构建开始日期的过滤器
SingleColumnValueFilter startDateFilter = new SingleColumnValueFilter(Bytes.toBytes(columnFamily),Bytes.toBytes(column),
CompareOperator.GREATER_OR_EQUAL,Bytes.toBytes(startValue));
//构建结束日期的过滤器
SingleColumnValueFilter endDateFilter = new SingleColumnValueFilter(Bytes.toBytes(columnFamily),Bytes.toBytes(column),
CompareOperator.LESS_OR_EQUAL,Bytes.toBytes(endValue));
//3.2 构建过滤器列表
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL,startDateFilter,endDateFilter);
//4.构建扫描器
scan.setFilter(filterList);
//5.执行scan扫描操作
ResultScanner resultScanner = table.getScanner(scan);
//6.迭代打印result
for (Result result:resultScanner) {
//6.1 打印rowkey
System.out.println("rowkey=>" + Bytes.toString(result.getRow()));
System.out.println("-------------------------------------------");
//6.2 迭代单元格列表
List<Cell> cells = result.listCells();
for (Cell cell:cells) {
//6.3打印数据
// 打印列簇名
System.out.print(Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength()));
//打印列名
//解决数值型数据乱码
String columnName = Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength());
//System.out.print(":" + Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength()));
System.out.println(":" + columnName);
//判断是否为数值型的列
if (columnName.equals("NUM_CURRENT") || columnName.equals("NUM_PREVIOUS")
|| columnName.equals("NUM_USAGE") || columnName.equals("TOTAL_MONEY")) {
//打印数值型值
System.out.println("=>" + Bytes.toDouble(cell.getValueArray(),cell.getValueOffset()));
}else{
//打印字符串值
System.out.println("=>" + Bytes.toString(cell.getValueArray(),cell.getValueOffset(),cell.getValueLength()));}
}
System.out.println("--------------------------------------------");
}
//7.关闭资源
resultScanner.close();
table.close();
}
}
源码在上边总的
创建一个名为water_bill的表,包含一个列簇info。


源码在上边总的
删除刚刚创建的表

查看结果
往water_bill中插入姓名列的数据
源码在上边总的
这里需要先把案例一在运行一遍把表创建好


出错了不知道为啥
重新运行一下

运行成功
查询显示rowkey为4944191的某列或者所有列的数据,




删除rowkey为“4944191”的数据



有一份10W条记录的抄表数据文件,需求将其导入hbase中

网盘链接
https://pan.baidu.com/s/1UEewxFODFPa2aREa-YjM2w?pwd=1234 提取码:1234
在hbase中,有一个import的MR作业,可以专门用来将数据导入到hbase中
用法:
hbase org.apache.hadoop.hbase.mapreduce.Import 表名 hdfs数据文件路径


hbase org.apache.hadoop.hbase.mapreduce.Import WATER_BILL /water_bill/

运行结果



hbase org.apache.hadoop.hbase.mapreduce.RowCounter "WATER_BILL"

在hbase中用scan+filter实现过滤查询。2020年6月份其实就是从2020年6月1号到2020年6月30日的所有抄表数据



输出结果代码改进

打印显示字符串数据是正常,但是如果HBase存储的是int、double、float等数值型数据时,显示就会乱码,解决的方法就是判断是否是数值型数据,如果是则进行相应的转换

显示结果

用法:
hbase org.apache.hadoop.hbase.mapreduce.Export 表名 hdfs路径

这篇hbase的java aip实例在这里也算是告一段落了,下一章(4)是关于hbase高可用的相关介绍和实现,希望大家一起学习,一起进步。
如遇侵权,请联系删除。
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],
我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam
1、接口请求基本操作1.1例子tips在view的选项可以zoomin调整窗口字帖大小。1、创建一个测试的workspace,并命名为test2、test后面新增一个addrequest3、选择发送GET,URL为一个开源的https://api.apiopen.top/api/sentences获取每日一句4、点击send查看内容Tips:如果提示出现Error:tunnelingsocketcouldnotbeestablished,statusCode=407错误,参照以下解决办法)关于tunnelingsocketcouldnotbeestablished,cause=getaddri
Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好
Ruby语言是否可以用于创建全新的移动操作系统或桌面操作系统,即是否可以用于系统编程? 最佳答案 嗯,现在有一些操作系统使用比C更高级的语言。基本上,ruby解释器本身需要用一些低级的东西来编写,并且需要一些引导加载代码将功能齐全的ruby解释器作为独立内核加载到内存中。一旦ruby解释器被引导并以内核模式(或innerrings之一)运行,就没有什么可以阻止您在其上构建整个操作系统。不幸的是,它可能会很慢。每个操作系统功能的垃圾收集可能会相当引人注目。ruby解释器将负责任务调度和网络堆栈等基本事情,使用垃圾收集框架会大大
假设我们有以下描述一个人的JSON对象:{"firstName":"John","lastName":"Smith","age":25,"address":{"streetAddress":"212ndStreet","city":"NewYork","state":"NY","postalCode":"10021"},"phoneNumber":[{"type":"home","number":"212555-1234"},{"type":"fax","number":"646555-4567"}]有人可以建议在Rails3中操作前一个对象的最优雅和最有效的方法吗?我希望能够:添加另