首頁技術(shù)文章正文

Java API接口怎樣操作HBase分布式數(shù)據(jù)庫?

更新時(shí)間:2020-12-22 來源:黑馬程序員 瀏覽量:

1577370495235_學(xué)IT就到黑馬程序員.gif

  HBase是由Java語言開發(fā)的,它對(duì)外提供了Java API的接口。接下來,通過一個(gè)表來列舉HBase常見的Java API,具體如表1所示。

  表1 常見的Java API
1608616576389_40.png

  接下來,通過Java API來操作HBase分布式數(shù)據(jù)庫,包括增、刪、改以及查等對(duì)數(shù)據(jù)表的操作,具體操作步驟如下:

  1. 創(chuàng)建工程并導(dǎo)入依賴

  創(chuàng)建一個(gè)名稱為“spark_chapter05”的Maven項(xiàng)目。然后在項(xiàng)目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包就會(huì)自動(dòng)下載,成功引入依賴如圖1所示。

1608616627511_41.jpg

圖1 成功引入的Jar包

創(chuàng)建Java類,連接集群

在項(xiàng)目spark_chapter05目錄/src/main/java下創(chuàng)建一個(gè)名為com.itcast.hbase包,并在該包下創(chuàng)建HBaseTest.java文件,該文件用于編寫Java測試類,構(gòu)建Configuration和Connection對(duì)象。初始化客戶端對(duì)象的具體操作步驟,如文件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對(duì)象
   private Configuration conf = null;
   //初始化連接
   private Connection conn = null;
   @Before
   public void init() throws Exception{
     //獲取Configuration對(duì)象
     conf = HBaseConfiguration.create();
     //對(duì)hbase客戶端來說,只需知道hbase所經(jīng)過的Zookeeper集群地址即可
     //因?yàn)閔base的客戶端找hbase讀寫數(shù)據(jù)完全不用經(jīng)過HMaster
     conf.set("hbase.zookeeper.quorum",
           "hadoop01:2181,hadoop02:2181,hadoop03:2181");
     //獲取連接
     conn = ConnectionFactory.createConnection(conf);
   }
 }

  在上述代碼中,第10-12行代碼是初始化Configuration配置對(duì)象和Connection連接對(duì)象;第13行代碼是注解@Before,用于Junit單元測試中控制程序最先執(zhí)行的注解,在這里可以保證初始化init()方法在程序中是最先執(zhí)行的;第16-22行代碼是初始化客戶端對(duì)象的初始化方法,主要是獲取Configuration配置對(duì)象和Connection連接對(duì)象以及指定Zookeeper集群的地址。

  3. 創(chuàng)建數(shù)據(jù)表

  在HBaseTest.Java文件中,定義一個(gè)方法createTable(),主要用于演示創(chuàng)建數(shù)據(jù)表操作。具體代碼如下:

  @Test
  public void createTable() throws Exception{
    //獲取表管理器對(duì)象
    Admin admin = conn.getAdmin();
    //創(chuàng)建表的描述對(duì)象,并指定表名
    HTableDescriptor tableDescriptor =new HTableDescriptor(TableName
                   .valueOf("t_user_info".getBytes()));
    //構(gòu)造第一個(gè)列族描述對(duì)象,并指定列族名
    HColumnDescriptor hcd1 = new HColumnDescriptor("base_info");
   //構(gòu)造第二個(gè)列族描述對(duì)象,并指定列族名
   HColumnDescriptor hcd2 = new HColumnDescriptor("extra_info");
   //為該列族設(shè)定一個(gè)版本數(shù)量,最小為1,最大為3
   hcd2.setVersions(1,3);
   //將列族描述對(duì)象添加到表描述對(duì)象中
   tableDescriptor.addFamily(hcd1).addFamily(hcd2);
   //利用表管理器來創(chuàng)建表
   admin.createTable(tableDescriptor);
   //關(guān)閉
   admin.close();
   conn.close();
 }

  在上述代碼中,第4-11行代碼獲取HBase表管理器對(duì)象admin、創(chuàng)建表的描述對(duì)象tableDescriptor并指定表名為t_user_info、創(chuàng)建兩個(gè)列族描述對(duì)象hcd1、hcd2并指定列族名分別為base_info和extra_info;第13行代碼為列族hcd2指定版本數(shù)量;第15行代碼將列族描述對(duì)象添加到表描述對(duì)象中;第16行代碼使用表管理器來創(chuàng)建表;第19-20行代碼關(guān)閉表管理器和連接對(duì)象,避免資源浪費(fèi)。

  運(yùn)行createTable()方法進(jìn)行測試,然后進(jìn)入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ù)庫中有一個(gè)名稱為t_user_info的數(shù)據(jù)表,說明數(shù)據(jù)表創(chuàng)建成功。

  4. 插入數(shù)據(jù)

  在HBaseTest.Java文件中,定義一個(gè)testPut()方法,主要用于演示在t_user_info表中插入數(shù)據(jù)的操作。具體代碼如下:

   @Test
   public void testPut() throws Exception {
     //創(chuàng)建table對(duì)象,通過table對(duì)象來添加數(shù)據(jù)
     Table table = conn.getTable(TableName.valueOf("t_user_info"));
     //創(chuàng)建一個(gè)集合,用于存放Put對(duì)象
     ArrayList<Put> puts = new ArrayList<Put>();
     //構(gòu)建put對(duì)象(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對(duì)象添加到一個(gè)集合中
    puts.add(put01);
    puts.add(put02);
    //提交所有的插入數(shù)據(jù)的記錄
    table.put(puts);
    //關(guān)閉
    table.close();
    conn.close();
  }

  上述代碼中,第4行代碼創(chuàng)建一個(gè)表對(duì)象table,用于插入數(shù)據(jù);第6行代碼創(chuàng)建一個(gè)集合puts,主要用于存放Put對(duì)象;第8-17行代碼創(chuàng)建了Put對(duì)象,用于構(gòu)建表中的行和列,這里創(chuàng)建了2個(gè)Put對(duì)象,并指定其行鍵;第19-22行代碼將前面創(chuàng)建的8個(gè)對(duì)象添加到puts集合中,并通過表對(duì)象table提交插入數(shù)據(jù)的記錄;第24-25行代碼關(guān)閉表對(duì)象和連接對(duì)象,避免資源浪費(fèi)。

  運(yùn)行testPut()方法進(jìn)行測試,然后在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文件中,定義一個(gè)testGet()方法用于演示查看行鍵為user001的數(shù)據(jù)。具體代碼如下:

   @Test
   public void testGet() throws Exception {
     //獲取一個(gè)table對(duì)象
     Table table = conn.getTable(TableName.valueOf("t_user_info"));
     // 創(chuàng)建get查詢參數(shù)對(duì)象,指定要獲取的是哪一行
     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)建一個(gè)表對(duì)象table,并指定要查看的數(shù)據(jù)表t_user_info;第6行代碼創(chuàng)建一個(gè)對(duì)象get,并指定要查看數(shù)據(jù)表行鍵為user001所有數(shù)據(jù);第8-10行代碼通過表對(duì)象table調(diào)用get()方法把行鍵為user001的所有數(shù)據(jù)放到集合cells中;第12-18行代碼遍歷打印集合cells中的所有數(shù)據(jù);第21-22行代碼關(guān)閉表對(duì)象和連接對(duì)象,避免資源浪費(fèi)。

  運(yùn)行testGet()方法進(jìn)行測試,IDEA控制臺(tái)輸出的內(nèi)容,如圖2所示。

1608616642130_43.jpg

圖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文件中,定義一個(gè)testScan()方法用于演示掃描t_user_info表中的所有數(shù)據(jù)。具體代碼如下:

   @Test
   public void testScan() throws Exception {
     //獲取table對(duì)象
     Table table = conn.getTable(TableName.valueOf("t_user_info"));
     //創(chuàng)建scan對(duì)象
     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對(duì)象
      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)建一個(gè)表對(duì)象table,并指定要查看的數(shù)據(jù)表t_user_info;第6行代碼創(chuàng)建一個(gè)全表掃描對(duì)象scan;第8-10行代碼通過表對(duì)象table調(diào)用getScanner()方法掃描表中的所有數(shù)據(jù),并將掃描到的所有數(shù)據(jù)存放入迭代器中;第12-35行代碼遍歷輸出迭代器中的數(shù)據(jù);第40-41代碼關(guān)閉表對(duì)象和連接對(duì)象,避免資源浪費(fèi)。

  運(yùn)行testScan()方法進(jìn)行測試,IDEA控制臺(tái)輸出的內(nèi)容,如圖3所示。

1608616654519_44.jpg

 圖3 掃描t_user_info表中的數(shù)據(jù)

  在圖3中,控制臺(tái)把t_user_info表中所有的數(shù)據(jù)都遍歷輸出。

  7. 刪除指定列的數(shù)據(jù)

  在HBaseTest.Java文件中,定義一個(gè)testDel()方法用于演示刪除t_user_info表中行鍵為user001的數(shù)據(jù)。具體代碼如下:

   @Test
   pubic void testDel() throws Exception {
     //獲取table對(duì)象
     Table table = conn.getTable(TableName.valueOf("t_user_info"));
     //獲取delete對(duì)象,需要一個(gè)rowkey
     Delete delete = new Delete("user001".getBytes());
     //在delete對(duì)象中指定要?jiǎng)h除的列族-列名稱
     delete.addColumn("base_info".getBytes(), "password".getBytes());
     //執(zhí)行刪除操作
    table.delete(delete);
    //關(guān)閉
    table.close();
    conn.close();
  }

  上述代碼中,第4行代碼創(chuàng)建一個(gè)表對(duì)象table,并指定要查看的數(shù)據(jù)表t_user_info;第6-8行代碼創(chuàng)建一個(gè)刪除對(duì)象delete,并指定要?jiǎng)h除行鍵為user001、列族為base_info、列名為password的這一條數(shù)據(jù);第10行代碼通過表對(duì)象table調(diào)用delete()方法執(zhí)行刪除操作;第12-13代碼關(guān)閉表對(duì)象和連接對(duì)象,避免資源浪費(fèi)。

  運(yùn)行testDel()方法進(jìn)行測試,然后在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文件中,定義一個(gè)testDrop()方法用于演示刪除t_user_info表。具體代碼如下:

   @Test  
   public void testDrop() throws Exception {
     //獲取一個(gè)表的管理器
     Admin admin = conn.getAdmin();
     //刪除表時(shí)先需要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)建一個(gè)表對(duì)象table;第6行代碼通過表對(duì)象table調(diào)用disable()方法將表t_user_info設(shè)置為不可用狀態(tài);第7行代碼通過表對(duì)象table調(diào)用deleteTable()方法執(zhí)行刪除表操作;第12-13代碼關(guān)閉表對(duì)象和連接對(duì)象,避免資源浪費(fèi)。

  運(yùn)行testDel()方法進(jìn)行測試,然后進(jìn)入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)被成功刪除。


猜你喜歡

詳解MapReduce編程的Map模型和Reduce模型

RDD轉(zhuǎn)換算子API過程演示【大數(shù)據(jù)文章】

如何使用IDEA工具開發(fā)一個(gè)WordCount單詞計(jì)數(shù)程序

黑馬程序員大數(shù)據(jù)培訓(xùn)課程 

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!