更新時間:2020-12-22 來源:黑馬程序員 瀏覽量:
HBase是由Java語言開發(fā)的,它對外提供了Java API的接口。接下來,通過一個表來列舉HBase常見的Java API,具體如表1所示。
表1 常見的Java API
接下來,通過Java API來操作HBase分布式數(shù)據(jù)庫,包括增、刪、改以及查等對數(shù)據(jù)表的操作,具體操作步驟如下:
1. 創(chuàng)建工程并導(dǎo)入依賴
創(chuàng)建一個名稱為“spark_chapter05”的Maven項目。然后在項目spark_chapter05中配置pom.xml文件,也就是引入HBase相關(guān)的依賴和單元測試的依賴,pom.xml文件添加的內(nèi)容具體如下所示:
<!--單元測試依賴-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--hbase客戶端依賴-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.1</version>
</dependency>
<!--hbase核心依賴-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>1.2.1</version>
</dependency>
當添加完相關(guān)依賴后,HBase相關(guān)Jar包就會自動下載,成功引入依賴如圖1所示。
圖1 成功引入的Jar包
創(chuàng)建Java類,連接集群
在項目spark_chapter05目錄/src/main/java下創(chuàng)建一個名為com.itcast.hbase包,并在該包下創(chuàng)建HBaseTest.java文件,該文件用于編寫Java測試類,構(gòu)建Configuration和Connection對象。初始化客戶端對象的具體操作步驟,如文件1所示。
文件1 HBaseTest.java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.*;
import java.util.*;
//todo:HBase Api操作
public class HBaseTest {
//初始化Configuration對象
private Configuration conf = null;
//初始化連接
private Connection conn = null;
@Before
public void init() throws Exception{
//獲取Configuration對象
conf = HBaseConfiguration.create();
//對hbase客戶端來說,只需知道hbase所經(jīng)過的Zookeeper集群地址即可
//因為hbase的客戶端找hbase讀寫數(shù)據(jù)完全不用經(jīng)過HMaster
conf.set("hbase.zookeeper.quorum",
"hadoop01:2181,hadoop02:2181,hadoop03:2181");
//獲取連接
conn = ConnectionFactory.createConnection(conf);
}
}
在上述代碼中,第10-12行代碼是初始化Configuration配置對象和Connection連接對象;第13行代碼是注解@Before,用于Junit單元測試中控制程序最先執(zhí)行的注解,在這里可以保證初始化init()方法在程序中是最先執(zhí)行的;第16-22行代碼是初始化客戶端對象的初始化方法,主要是獲取Configuration配置對象和Connection連接對象以及指定Zookeeper集群的地址。
3. 創(chuàng)建數(shù)據(jù)表
在HBaseTest.Java文件中,定義一個方法createTable(),主要用于演示創(chuàng)建數(shù)據(jù)表操作。具體代碼如下:
@Test
public void createTable() throws Exception{
//獲取表管理器對象
Admin admin = conn.getAdmin();
//創(chuàng)建表的描述對象,并指定表名
HTableDescriptor tableDescriptor =new HTableDescriptor(TableName
.valueOf("t_user_info".getBytes()));
//構(gòu)造第一個列族描述對象,并指定列族名
HColumnDescriptor hcd1 = new HColumnDescriptor("base_info");
//構(gòu)造第二個列族描述對象,并指定列族名
HColumnDescriptor hcd2 = new HColumnDescriptor("extra_info");
//為該列族設(shè)定一個版本數(shù)量,最小為1,最大為3
hcd2.setVersions(1,3);
//將列族描述對象添加到表描述對象中
tableDescriptor.addFamily(hcd1).addFamily(hcd2);
//利用表管理器來創(chuàng)建表
admin.createTable(tableDescriptor);
//關(guān)閉
admin.close();
conn.close();
}
在上述代碼中,第4-11行代碼獲取HBase表管理器對象admin、創(chuàng)建表的描述對象tableDescriptor并指定表名為t_user_info、創(chuàng)建兩個列族描述對象hcd1、hcd2并指定列族名分別為base_info和extra_info;第13行代碼為列族hcd2指定版本數(shù)量;第15行代碼將列族描述對象添加到表描述對象中;第16行代碼使用表管理器來創(chuàng)建表;第19-20行代碼關(guān)閉表管理器和連接對象,避免資源浪費。
運行createTable()方法進行測試,然后進入HBase Shell交互式頁面,執(zhí)行“l(fā)ist”命令查看數(shù)據(jù)庫,具體代碼如下:
hbase(main):022:0> list
TABLE
t_user_info
1 row(s) in 0.0200 seconds
=> ["t_user_info"]
在上述代碼中,數(shù)據(jù)庫中有一個名稱為t_user_info的數(shù)據(jù)表,說明數(shù)據(jù)表創(chuàng)建成功。
4. 插入數(shù)據(jù)
在HBaseTest.Java文件中,定義一個testPut()方法,主要用于演示在t_user_info表中插入數(shù)據(jù)的操作。具體代碼如下:
@Test
public void testPut() throws Exception {
//創(chuàng)建table對象,通過table對象來添加數(shù)據(jù)
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//創(chuàng)建一個集合,用于存放Put對象
ArrayList<Put> puts = new ArrayList<Put>();
//構(gòu)建put對象(KV形式),并指定其行鍵
Put put01 = new Put(Bytes.toBytes("user001"));
put01.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("username"),
Bytes.toBytes("zhangsan"));
put01.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("password"),
Bytes.toBytes("123456"));
Put put02 = new Put("user002".getBytes());
put02.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("username"),
Bytes.toBytes("lisi"));
put02.addColumn(Bytes.toBytes("extra_info"),Bytes.toBytes("married"),
Bytes.toBytes("false"));
//把所有的put對象添加到一個集合中
puts.add(put01);
puts.add(put02);
//提交所有的插入數(shù)據(jù)的記錄
table.put(puts);
//關(guān)閉
table.close();
conn.close();
}
上述代碼中,第4行代碼創(chuàng)建一個表對象table,用于插入數(shù)據(jù);第6行代碼創(chuàng)建一個集合puts,主要用于存放Put對象;第8-17行代碼創(chuàng)建了Put對象,用于構(gòu)建表中的行和列,這里創(chuàng)建了2個Put對象,并指定其行鍵;第19-22行代碼將前面創(chuàng)建的8個對象添加到puts集合中,并通過表對象table提交插入數(shù)據(jù)的記錄;第24-25行代碼關(guān)閉表對象和連接對象,避免資源浪費。
運行testPut()方法進行測試,然后在HBase Shell交互式頁面執(zhí)行“scan”命令,查看數(shù)據(jù)表t_user_info中的數(shù)據(jù),具體代碼如下:
hbase(main):023:0> scan 't_user_info'ROW COLUMN+CELL
user001 column=base_info:password,timestamp=1545759238044,value=123456
user001 column=base_info:username, timestamp=1545759238044, value=zhangsan
user002 column=base_info:username, timestamp=1545759238044, value=lisi
user002 column=extra_info:married, timestamp=1545759238044, value=false2 row(s) in 0.0370 seconds
5. 查看指定字段的數(shù)據(jù)
在HBaseTest.Java文件中,定義一個testGet()方法用于演示查看行鍵為user001的數(shù)據(jù)。具體代碼如下:
@Test
public void testGet() throws Exception {
//獲取一個table對象
Table table = conn.getTable(TableName.valueOf("t_user_info"));
// 創(chuàng)建get查詢參數(shù)對象,指定要獲取的是哪一行
Get get = new Get("user001".getBytes());
//返回查詢結(jié)果的數(shù)據(jù)
Result result = table.get(get);
//獲取結(jié)果中的所有cell
List<Cell> cells = result.listCells();
//遍歷所有的cell
for(Cell cell:cells){
//獲取行鍵
System.out.println("行:"+Bytes.toString(CellUtil.cloneRow(cell)));
//得到列族
System.out.println("列族:"+Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:"+Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:"+Bytes.toString(CellUtil.cloneValue(cell)));
}
//關(guān)閉
table.close();
conn.close();
}
上述代碼中,第4行代碼創(chuàng)建一個表對象table,并指定要查看的數(shù)據(jù)表t_user_info;第6行代碼創(chuàng)建一個對象get,并指定要查看數(shù)據(jù)表行鍵為user001所有數(shù)據(jù);第8-10行代碼通過表對象table調(diào)用get()方法把行鍵為user001的所有數(shù)據(jù)放到集合cells中;第12-18行代碼遍歷打印集合cells中的所有數(shù)據(jù);第21-22行代碼關(guān)閉表對象和連接對象,避免資源浪費。
運行testGet()方法進行測試,IDEA控制臺輸出的內(nèi)容,如圖2所示。
圖2 查看數(shù)據(jù)表t_user_info中行鍵為user001的數(shù)據(jù)
從圖2可以看出,行鍵為user001的數(shù)據(jù)一共有兩條,一條是行鍵為user001、列族為base_info、列為password、值為123456的數(shù)據(jù);另一條是行鍵為user001、列族為baseinfo、列為username、值為zhangsan的數(shù)據(jù)。
6. 掃描數(shù)據(jù)
在HBaseTest.Java文件中,定義一個testScan()方法用于演示掃描t_user_info表中的所有數(shù)據(jù)。具體代碼如下:
@Test
public void testScan() throws Exception {
//獲取table對象
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//創(chuàng)建scan對象
Scan scan = new Scan();
//獲取查詢的數(shù)據(jù)
ResultScanner scanner = table.getScanner(scan);
//獲取ResultScanner所有數(shù)據(jù),返回迭代器
Iterator<Result> iter = scanner.iterator();
//遍歷迭代器
while (iter.hasNext()) {
//獲取當前每一行結(jié)果數(shù)據(jù)
Result result = iter.next();
//獲取當前每一行中所有的cell對象
List<Cell> cells = result.listCells();
//迭代所有的cell
for(Cell c:cells){
//獲取行鍵
byte[] rowArray = c.getRowArray();
//獲取列族
byte[] familyArray = c.getFamilyArray();
//獲取列族下的列名稱
byte[] qualifierArray = c.getQualifierArray();
//列字段的值
byte[] valueArray = c.getValueArray();
//打印rowArray、familyArray、qualifierArray、valueArray
System.out.println("行鍵:"+new String(rowArray,c.getRowOffset(),
c.getRowLength()));
System.out.print("列族:"+ new String(familyArray,c.getFamilyOffset(),
c.getFamilyLength()));
System.out.print(" "+"列:" + new String(qualifierArray,
c.getQualifierOffset(),c.getQualifierLength()));
System.out.println(" " +"值:" new String(valueArray,
c.getValueOffset(), c.getValueLength()));
}
System.out.println("-----------------------");
}
//關(guān)閉
table.close();
conn.close();
}
上述代碼中,第4行代碼創(chuàng)建一個表對象table,并指定要查看的數(shù)據(jù)表t_user_info;第6行代碼創(chuàng)建一個全表掃描對象scan;第8-10行代碼通過表對象table調(diào)用getScanner()方法掃描表中的所有數(shù)據(jù),并將掃描到的所有數(shù)據(jù)存放入迭代器中;第12-35行代碼遍歷輸出迭代器中的數(shù)據(jù);第40-41代碼關(guān)閉表對象和連接對象,避免資源浪費。
運行testScan()方法進行測試,IDEA控制臺輸出的內(nèi)容,如圖3所示。
圖3 掃描t_user_info表中的數(shù)據(jù)
在圖3中,控制臺把t_user_info表中所有的數(shù)據(jù)都遍歷輸出。
7. 刪除指定列的數(shù)據(jù)
在HBaseTest.Java文件中,定義一個testDel()方法用于演示刪除t_user_info表中行鍵為user001的數(shù)據(jù)。具體代碼如下:
@Test
pubic void testDel() throws Exception {
//獲取table對象
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//獲取delete對象,需要一個rowkey
Delete delete = new Delete("user001".getBytes());
//在delete對象中指定要刪除的列族-列名稱
delete.addColumn("base_info".getBytes(), "password".getBytes());
//執(zhí)行刪除操作
table.delete(delete);
//關(guān)閉
table.close();
conn.close();
}
上述代碼中,第4行代碼創(chuàng)建一個表對象table,并指定要查看的數(shù)據(jù)表t_user_info;第6-8行代碼創(chuàng)建一個刪除對象delete,并指定要刪除行鍵為user001、列族為base_info、列名為password的這一條數(shù)據(jù);第10行代碼通過表對象table調(diào)用delete()方法執(zhí)行刪除操作;第12-13代碼關(guān)閉表對象和連接對象,避免資源浪費。
運行testDel()方法進行測試,然后在HBase Shell交互式頁面執(zhí)行“scan”命令,查看數(shù)據(jù)表t_user_info中的數(shù)據(jù),具體代碼如下:
hbase(main):024:0> scan 't_user_info'ROW COLUMN+CELL
user001 column=base_info:username,timestamp=1548486421815,value=zhangsan
user002 column=base_info:username, timestamp=1548486421815, value=lisi
user002 column=extra_info:married,timestamp=1548486421815,value=false
2 row(s) in 0.0350 seconds
在上述代碼中,發(fā)現(xiàn)行鍵為“user001”、列族為“base_info”且列名為“password”的一列數(shù)據(jù)沒有顯示出來,說明這一列數(shù)據(jù)已經(jīng)被刪除。
8. 刪除表
在HBaseTest.Java文件中,定義一個testDrop()方法用于演示刪除t_user_info表。具體代碼如下:
@Test
public void testDrop() throws Exception {
//獲取一個表的管理器
Admin admin = conn.getAdmin();
//刪除表時先需要disable,將表置為不可用,然后在delete
admin.disableTable(TableName.valueOf("t_user_info"));
admin.deleteTable(TableName.valueOf("t_user_info"));
//關(guān)閉
admin.close();
conn.close();
}
在上述代碼中,第4行代碼創(chuàng)建一個表對象table;第6行代碼通過表對象table調(diào)用disable()方法將表t_user_info設(shè)置為不可用狀態(tài);第7行代碼通過表對象table調(diào)用deleteTable()方法執(zhí)行刪除表操作;第12-13代碼關(guān)閉表對象和連接對象,避免資源浪費。
運行testDel()方法進行測試,然后進入HBase Shell的交互式界面,執(zhí)行“l(fā)ist”命令查看HBase分布式數(shù)據(jù)庫中的表,具體代碼如下:
hbase(main):024:0> list
TABLE
0 row(s) in 0.1430 seconds
=> []
在上述代碼中,輸出的結(jié)果為[ ],表示數(shù)據(jù)庫為空的,說明t_user_info表已經(jīng)被成功刪除。
猜你喜歡
RDD轉(zhuǎn)換算子API過程演示【大數(shù)據(jù)文章】