更新時間: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>
當(dāng)添加完相關(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()) { //獲取當(dāng)前每一行結(jié)果數(shù)據(jù) Result result = iter.next(); //獲取當(dāng)前每一行中所有的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ù)文章】