Apache Hbase 系列文章
1、hbase-2.1.0介紹及分布式集群部署、HA集群部署、驗證、硬件配置推薦
2、hbase-2.1.0 shell基本操作詳解
3、HBase的java API基本操作(創(chuàng)建、刪除表以及對數(shù)據(jù)的添加、刪除、查詢以及多條件查詢)
4、HBase使用(namespace、數(shù)據(jù)分區(qū)、rowkey設(shè)計、原生api訪問hbase)
5、Apache Phoenix(5.0.0-5.1.2) 介紹及部署、使用(基本使用、綜合使用、二級索引示例)、數(shù)據(jù)分區(qū)示例
6、Base批量裝載——Bulk load(示例一:基本使用示例)
7、Base批量裝載-Bulk load(示例二:寫千萬級數(shù)據(jù)-mysql數(shù)據(jù)以O(shè)RCFile寫入hdfs,然后導(dǎo)入hbase)
8、HBase批量裝載-Bulk load(示例三:寫千萬級數(shù)據(jù)-mysql數(shù)據(jù)直接寫成Hbase需要的數(shù)據(jù),然后導(dǎo)入hbase)
本文主要介紹了通過java api操作hbase的基本示例。
本文依賴hbase環(huán)境可用。
本分主要分為2個部分,即maven依賴和源碼示例。
一、maven依賴
1、pom.xml
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2、復(fù)制HBase和Hadoop配置文件
將以下二個配置文件復(fù)制到resource目錄中
hbase-site.xml
core-site.xml
注意:在哪個環(huán)境操作就使用哪個環(huán)境的配置文件,或者開發(fā)測試時直接在代碼中設(shè)置zookeeper的地址
二、源碼
要操作Hbase也需要建立Hbase的連接。此處我們?nèi)匀皇褂肨estNG來編寫測試。使用@BeforeTest初始化HBase連接,創(chuàng)建admin對象、@AfterTest關(guān)閉連接。文章來源:http://www.zghlxwxcb.cn/news/detail-478885.html
1、創(chuàng)建/刪除表
1)、實現(xiàn)步驟
- 使用HbaseConfiguration.create()創(chuàng)建Hbase配置
- 使用ConnectionFactory.createConnection()創(chuàng)建Hbase連接
- 要創(chuàng)建表,需要基于Hbase連接獲取admin管理對象
- 使用admin.close、connection.close關(guān)閉連接
2)、實現(xiàn)
- 以下是將配置文件放在java工程的resource目錄中示例
import static org.junit.Assert.*;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* 創(chuàng)建和刪除表操作
*
* @author alanchan
*
*/
public class AdminTest {
private Configuration configuration;
private Connection connection;
private Admin admin;
private String table_Name = "TEST";
@Before
public void beforeTest() throws IOException {
configuration = HBaseConfiguration.create();
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
}
@Test
public void createTableTest() throws IOException {
TableName tableName = TableName.valueOf(table_Name);
// 1. 判斷表是否存在
if (admin.tableExists(tableName)) {
// a) 存在,則退出
return;
}
// 構(gòu)建表
// 2. 使用TableDescriptorBuilder.newBuilder構(gòu)建表描述構(gòu)建器
// TableDescriptor: 表描述器,描述這個表有幾個列簇、其他的屬性都是在這里可以配置
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);
// 3. 使用ColumnFamilyDescriptorBuilder.newBuilder構(gòu)建列簇描述構(gòu)建器
// 創(chuàng)建列簇也需要有列簇的描述器,需要用一個構(gòu)建起來構(gòu)建ColumnFamilyDescriptor
// 經(jīng)常會使用到一個工具類:Bytes(hbase包下的Bytes工具類)
// 這個工具類可以將字符串、long、double類型轉(zhuǎn)換成byte[]數(shù)組
// 也可以將byte[]數(shù)組轉(zhuǎn)換為指定類型
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder
.newBuilder(Bytes.toBytes("C1"));
// 4. 構(gòu)建列簇描述,構(gòu)建表描述
ColumnFamilyDescriptor cfDes = columnFamilyDescriptorBuilder.build();
// 建立表和列簇的關(guān)聯(lián)
tableDescriptorBuilder.setColumnFamily(cfDes);
TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
// 5. 創(chuàng)建表
admin.createTable(tableDescriptor);
assertTrue("表創(chuàng)建成功", admin.tableExists(tableName));
}
@Test
public void deleteTableTest() throws IOException {
TableName tableName = TableName.valueOf(table_Name);
// 1. 判斷表是否存在
if (admin.tableExists(tableName)) {
// 2.如果存在,則禁用表
admin.disableTable(tableName);
// 3.再刪除表
admin.deleteTable(tableName);
}
assertFalse("表刪除成功", admin.tableExists(tableName));
}
@After
public void afterTest() throws IOException {
admin.close();
connection.close();
}
}
- 以下是配置文件沒有放在java工程的resource目錄下示例
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* 該示例是基于core-site.xml和hbase-site.xml文件沒有的情況下,直接在代碼中配置zookeeper信息
*
* @author alanchan
*
*/
public class AdminTestNoXmlConf {
private Configuration configuration;
private Connection connection;
private Admin admin;
private String table_Name = "TEST";
@Before
public void beforeTest() throws IOException {
configuration = HBaseConfiguration.create();
// 創(chuàng)建配置項,設(shè)置zookeeper的參數(shù)
configuration.set("hbase.zookeeper.quorum", "server1,server2,server3");
configuration.set("hbase.zookeeper.property.clientPort", "2181");
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
}
@Test
public void createTableTest() throws IOException {
TableName tableName = TableName.valueOf(table_Name);
// 1. 判斷表是否存在
if (admin.tableExists(tableName)) {
// a) 存在,則退出
return;
}
// 構(gòu)建表
// 2. 使用TableDescriptorBuilder.newBuilder構(gòu)建表描述構(gòu)建器
// TableDescriptor: 表描述器,描述這個表有幾個列簇、其他的屬性都是在這里可以配置
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);
// 3. 使用ColumnFamilyDescriptorBuilder.newBuilder構(gòu)建列簇描述構(gòu)建器
// 創(chuàng)建列簇也需要有列簇的描述器,需要用一個構(gòu)建起來構(gòu)建ColumnFamilyDescriptor
// 經(jīng)常會使用到一個工具類:Bytes(hbase包下的Bytes工具類)
// 這個工具類可以將字符串、long、double類型轉(zhuǎn)換成byte[]數(shù)組
// 也可以將byte[]數(shù)組轉(zhuǎn)換為指定類型
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder
.newBuilder(Bytes.toBytes("C1"));
// 4. 構(gòu)建列簇描述,構(gòu)建表描述
ColumnFamilyDescriptor cfDes = columnFamilyDescriptorBuilder.build();
// 建立表和列簇的關(guān)聯(lián)
tableDescriptorBuilder.setColumnFamily(cfDes);
TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
// 5. 創(chuàng)建表
admin.createTable(tableDescriptor);
assertTrue("表創(chuàng)建成功", admin.tableExists(tableName));
}
@Test
public void deleteTableTest() throws IOException {
TableName tableName = TableName.valueOf(table_Name);
// 1. 判斷表是否存在
if (admin.tableExists(tableName)) {
// 2.如果存在,則禁用表
admin.disableTable(tableName);
// 3.再刪除表
admin.deleteTable(tableName);
}
assertFalse("表刪除成功", admin.tableExists(tableName));
}
@After
public void afterTest() throws IOException {
admin.close();
connection.close();
}
}
2、CRUD操作-put、get、delete、scan、filter實現(xiàn)示例
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
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.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import lombok.extern.slf4j.Slf4j;
/**
* 添加、查詢和刪除數(shù)據(jù)。
* 修改數(shù)據(jù)可以看作是重新Put添加數(shù)據(jù)。
*
* @author alanchan
*
*/
@Slf4j
public class OperatorTest {
// Connection是線程安全的
private Connection connection;
private TableName TABLE_NAME = TableName.valueOf("TEST");
@Before
public void beforeTest() throws IOException {
// 1. 使用HbaseConfiguration.create()創(chuàng)建Hbase配置
Configuration configuration = HBaseConfiguration.create();
// 2. 使用ConnectionFactory.createConnection()創(chuàng)建Hbase連接
connection = ConnectionFactory.createConnection(configuration);
}
@Test
public void putTest() throws IOException {
// 1. 使用Hbase連接獲取Htable
Table table = connection.getTable(TABLE_NAME);
// 2. 構(gòu)建ROWKEY、列簇名、列名
String rowkey = "4944191";
String columnFamily = "C1";
String columnName = "NAME";
String columnNameADDRESS = "ADDRESS";
String columnNameSEX = "SEX";
String columnNamePAY_DATE = "PAY_DATE";
String columnNameNUM_CURRENT = "NUM_CURRENT";
String columnNameNUM_PREVIOUS = "NUM_PREVIOUS";
String columnNameNUM_USAGE = "NUM_USAGE";
String columnNameTOTAL_MONEY = "TOTAL_MONEY";
String columnNameRECORD_DATE = "RECORD_DATE";
String columnNameLATEST_DATE = "LATEST_DATE";
// value:
// 3. 構(gòu)建Put對象(對應(yīng)put命令)
Put put = new Put(Bytes.toBytes(rowkey));
// 4. 添加姓名列
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName), Bytes.toBytes("登衛(wèi)紅"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameADDRESS), Bytes.toBytes("貴州省銅仁市德江縣7單元267室"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameSEX), Bytes.toBytes("男"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNamePAY_DATE), Bytes.toBytes("2020-05-10"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameNUM_CURRENT), Bytes.toBytes("308.1"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameNUM_PREVIOUS), Bytes.toBytes("283.1"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameNUM_USAGE), Bytes.toBytes("25"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameTOTAL_MONEY), Bytes.toBytes("150"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameRECORD_DATE), Bytes.toBytes("2020-04-25"));
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnNameLATEST_DATE), Bytes.toBytes("2020-06-09"));
// 5. 使用Htable表對象執(zhí)行put操作
table.put(put);
// 6. 關(guān)閉Htable表對象
// HTable是一個輕量級的對象,可以經(jīng)常創(chuàng)建
// HTable它是一個非線程安全的API
table.close();
}
@Test
public void getTest() throws IOException {
// 1. 獲取HTable
Table table = connection.getTable(TABLE_NAME);
// 2. 使用rowkey構(gòu)建Get對象
Get get = new Get(Bytes.toBytes("4944191"));
// 3. 執(zhí)行g(shù)et請求
Result result = table.get(get);
// 4. 獲取所有單元格
// 列出所有的單元格
List<Cell> cellList = result.listCells();
// 5. 打印rowkey
byte[] rowkey = result.getRow();
log.info("rowkey={}", Bytes.toString(rowkey));
// 6. 迭代單元格列表
for (Cell cell : cellList) {
// 將字節(jié)數(shù)組轉(zhuǎn)換為字符串
// 獲取列簇的名稱
String cf = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
// 獲取列的名稱
String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
cell.getQualifierLength());
// 獲取值
String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
log.info("列簇:列->值={}:{}->{}", cf, columnName, value);
}
// 7. 關(guān)閉表
table.close();
}
@Test
public void deleteTest() throws IOException {
// 1. 獲取HTable對象
Table table = connection.getTable(TABLE_NAME);
// 2. 根據(jù)rowkey構(gòu)建delete對象
Delete delete = new Delete(Bytes.toBytes("4944191"));
// 3. 執(zhí)行delete請求
table.delete(delete);
// 4. 關(guān)閉表
table.close();
}
@After
public void afterTest() throws IOException {
connection.close();
}
// 查詢2020年6月份所有用戶的用水量
//
// hbase(main):117:0> get 'WATER_BILL','9951726', {FORMATTER => 'toString'}
// COLUMN CELL
// C1:ADDRESS timestamp=1588911489455, value=安徽省宣城市市轄區(qū)13單元187室
// C1:LATEST_DATE timestamp=1588911489455, value=2019-07-03
// C1:NAME timestamp=1588911489455, value=檢喜云
// C1:NUM_CURRENT timestamp=1588911489455, value=@}?fffff
// C1:NUM_PREVIOUS timestamp=1588911489455, value=@z陙???
// C1:NUM_USAGE timestamp=1588911489455, value=@9
// C1:PAY_DATE timestamp=1588911489455, value=2020-09-26
// C1:RECORD_DATE timestamp=1588911489455, value=2019-07-18
// C1:SEX timestamp=1588911489455, value=男
// C1:TOTAL_MONEY timestamp=1588911489455, value=@`?
@Test
public void scanFilterTest() throws IOException {
// 1. 獲取表
Table table = connection.getTable(TABLE_NAME);
// 2. 構(gòu)建scan請求對象
Scan scan = new Scan();
// 3. 構(gòu)建兩個過濾器
// a) 構(gòu)建兩個日期范圍過濾器(注意此處請使用RECORD_DATE——抄表日期比較
SingleColumnValueFilter startFilter = new SingleColumnValueFilter(Bytes.toBytes("C1"),
Bytes.toBytes("RECORD_DATE"), CompareOperator.GREATER_OR_EQUAL,
new BinaryComparator(Bytes.toBytes("2020-06-01")));
SingleColumnValueFilter endFilter = new SingleColumnValueFilter(Bytes.toBytes("C1"),
Bytes.toBytes("RECORD_DATE"), CompareOperator.LESS_OR_EQUAL,
new BinaryComparator(Bytes.toBytes("2020-06-30")));
// b) 構(gòu)建過濾器列表
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, startFilter, endFilter);
// 4. 執(zhí)行scan掃描請求
scan.setFilter(filterList);
ResultScanner resultScanner = table.getScanner(scan);
Iterator<Result> iterator = resultScanner.iterator();
// 5. 迭代打印result
while (iterator.hasNext()) {
Result result = iterator.next();
// 列出所有的單元格
List<Cell> cellList = result.listCells();
// 5. 打印rowkey
byte[] rowkey = result.getRow();
log.info("rowkey={}", Bytes.toString(rowkey));
// 6. 迭代單元格列表
for (Cell cell : cellList) {
// 將字節(jié)數(shù)組轉(zhuǎn)換為字符串
// 獲取列簇的名稱
String cf = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
// 獲取列的名稱
String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),cell.getQualifierLength());
String value = "";
if (columnName.equals("NUM_CURRENT") || columnName.equals("NUM_PREVIOUS") || columnName.equals("NUM_USAGE") || columnName.equals("TOTAL_MONEY")) {
value = Bytes.toDouble(cell.getValueArray()) + "";
} else {
// 獲取值
value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
}
log.info("列簇:列->值={}:{}->{}", cf, columnName, value);
}
}
// 7. 關(guān)閉ResultScanner
resultScanner.close();
// 8. 關(guān)閉表
table.close();
}
}
以上,完成了通過java api簡單操作hbase的示例,如果需要更多更深入的使用,則需要參看官方文檔。文章來源地址http://www.zghlxwxcb.cn/news/detail-478885.html
到了這里,關(guān)于3、HBase的java API基本操作(創(chuàng)建、刪除表以及對數(shù)據(jù)的添加、刪除、查詢以及多條件查詢)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!