1. 程式人生 > >Java API連線HBase 進行增刪查改操作

Java API連線HBase 進行增刪查改操作

  1. 準備工作
    (1).建立maven工程,新增以下依賴,匯入jar包
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId
>
hbase-server</artifactId> <version>1.2.6</version> </dependency>

(2) 建立hbase-site.xml檔案配置hbase的連線資訊

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
<property>
    <name>hbase.zookeeper.quorum</name
>
<value>master,slave1,slave2</value> <description>The directory shared by RegionServers.</description> </property> <property> <name>hbase.zookeeper.property.clientport</name> <value>2181</value> </property> </configuration
>

(3) 開啟hbase服務,準備工作完成。
2. 通過configuration獲取hbase連線

public Connection connection;
    // 用HBaseconfiguration初始化配置資訊是會自動載入當前應用的classpath下的hbase-site.xml
    public static Configuration configuration = HBaseConfiguration.create();

    public HbaseTest() throws Exception {
        // 對connection進行初始化、
        // 當然也可以手動載入配置檔案,手動載入配置檔案時要呼叫configuration的addResource方法
        // configuration.addResource("hbase-site.xml");
        connection = ConnectionFactory.createConnection(configuration);

3 、 通過java API建立表、刪除表

  • 獲取連線後就可以通過API操作HBase了,對錶的操做是通過Admin類的方法進行操作的。
    public void createTable(String tableName , String... cf1)throws Exception{
        Admin admin = connection.getAdmin();
        //HTD需要TableName型別的tableName,建立TableName型別的tableName
        TableName tbName = TableName.valueOf(tableName);
        //判斷表述否已存在,不存在則建立表
        if(admin.tableExists(tbName)){
            System.err.println("表" + tableName + "已存在!");
            return;
        }
        //通過HTableDescriptor建立一個HTableDescriptor將表的描述傳到createTable引數中
        HTableDescriptor HTD = new HTableDescriptor(tbName);
        //為描述器新增表的詳細引數
        for(String cf : cf1){
            // 建立HColumnDescriptor物件新增表的詳細的描述
            HColumnDescriptor HCD =new HColumnDescriptor(cf);
            HTD.addFamily(HCD);
        }
        //呼叫createtable方法建立表
        admin.createTable(HTD);
    }
  • 刪除表
   public void deleteTable(String tableName) throws Exception {
        Admin admin = connection.getAdmin();
        //通過tableName建立表名
        TableName tbName = TableName.valueOf(tableName);
        //判斷表是否存在,若存在就刪除,不存在就退出
        if (admin.tableExists(tbName)) {
            //首先將表解除佔用,否則無法刪除
            admin.disableTable(tbName);
            //呼叫delete方法
            admin.deleteTable(tbName);
            System.err.println("表" + tableName + "已刪除");
        }else{
            System.err.println("表" + tableName + "不存在!");
        }
    }
}
  • 向表中寫入資料
    操作表中的資料要用Table類下的方法,寫入資料要呼叫put方法
 public void putData() throws Exception{
    //通過表名獲取tbName
        TableName tbname = TableName.valueOf("bd14:fromJava");
        //通過connection獲取相應的表
        Table table =connection.getTable(tbname); 
        //建立Random物件以作為隨機引數
        Random random = new Random();
        //hbase支援批量寫入資料,建立Put集合來存放批量的資料
        List<Put> batput = new ArrayList<>();
        //迴圈10次,建立10組測試資料放入list中
        for(int i=0;i<10;i++){
            //例項化put物件,傳入行鍵
            Put put =new Put(Bytes.toBytes("rowkey_"+i));
            //呼叫addcolum方法,向i簇中新增欄位
            put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("username"),Bytes.toBytes("un_"+i));
            put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("age"),Bytes.toBytes(random.nextInt(50)+1));
            put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("birthday"),Bytes.toBytes("2017"+i));
            put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("phone"),Bytes.toBytes("phone:"+i));
            put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("郵箱"),Bytes.toBytes("郵箱:"+i));
            //將測試資料新增到list中
            batput.add(put);
        }
        //呼叫put方法將list中的測試資料寫入hbase
        table.put(batput);
        System.err.println("資料插入完成!");
    }
  • 查詢資料
    • 方法1:使用CellScanner類遍歷資料表
public void getData() throws Exception{
        //獲取想要查詢的表的TableName
        TableName tbname = TableName.valueOf("bd14:fromJava");
        //通過tbName獲得Table物件
        Table table =connection.getTable(tbname);
        //建立Get的集合以承接查詢的條件
        List<Get> gets = new ArrayList<>();
        //迴圈五次,取前五個測試資料
        for(int i=0;i<5;i++){
            //就將查詢條件放入get物件中
            Get get = new Get(Bytes.toBytes("rowkey_"+i));
            //將get物件放入聚合
            gets.add(get);
        }
        //呼叫table.get方法傳入查詢條件,獲得查詢的結果的陣列
        Result[] results = table.get(gets);
        //遍歷結果陣列,利用CellScanner配合cellUtil獲得對應的資料
        for (Result result : results) {
            //呼叫result.cellscanner建立scanner物件
            CellScanner cellScanner = result.cellScanner();
            //遍歷結果集,取出查詢結果,
            //如果存在下一個cell則advandce方法返回true,且current方法會返回一個有效的cell,可以當作迴圈條件
            while (cellScanner.advance()) {
                //current方法返回一個有效的cell
                 Cell cell = cellScanner.current();
                 //使用CellUtil呼叫相應的方法獲取想用的資料,並利用Bytes.toString方法將結果轉換為string輸出
                 String family = Bytes.toString(CellUtil.cloneFamily(cell));
                 String qualify = Bytes.toString(CellUtil.cloneQualifier(cell));
                 String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
                 String value = Bytes.toString(CellUtil.cloneValue(cell));
                 System.err.println(family+"_"+qualify+"_"+rowkey+"_"+value);
            }
        }
    }
  • 方法 2: 通過getmap方法獲取結果集,並迴圈遍歷map獲取資料
public void getData() throws Exception{
        TableName tbname = TableName.valueOf("bd14:fromJava");
        Table table =connection.getTable(tbname);
        List<Get> gets = new ArrayList<>();
        for(int i=0;i<5;i++){
            Get get = new Get(Bytes.toBytes("rowkey_"+i));
            gets.add(get);
        }
        Result[] results = table.get(gets);
        for (Result result : results) {
            NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = result.getMap();
            for(byte[] cf : map.keySet()){
                NavigableMap<byte[], NavigableMap<Long, byte[]>> valueWithColumnQualify = map.get(cf);
                for(byte[] columnQualify:valueWithColumnQualify.keySet()){
                    NavigableMap<Long, byte[]> valueWithTimestamp = valueWithColumnQualify.get(columnQualify);
                    for (Long ts : valueWithTimestamp.keySet()) {
                        byte[] value = valueWithTimestamp.get(ts);
                         String rowKey = Bytes.toString(result.getRow());
                         String columnFamily = Bytes.toString(cf);
                         String columnqualify = Bytes.toString(columnQualify);
                         String timestamp =new Date(ts)+"";
                         String values = Bytes.toString(columnQualify);
                        System.out.println(rowKey+"-"+columnFamily+"-"+columnqualify+"-"+timestamp+"-"+values);
                    }
                }
            }
        }
    }
  • 方法 3:巢狀遍歷結果物件,利用CellUtil獲取資料
    public void getData() throws Exception{
        TableName tbname = TableName.valueOf("bd14:fromJava");
        Table table =connection.getTable(tbname);
        List<Get> gets = new ArrayList<>();
        for(int i=0;i<5;i++){
            Get get = new Get(Bytes.toBytes("rowkey_"+i));
            gets.add(get);
        }
        Result[] results = table.get(gets);
        //遍歷結果物件results
        for (Result result : results) {
        //巢狀遍歷result獲取cell
            for(Cell cell : result.listCells()){
            //使用CellUtil工具類直接獲取cell中的資料
                 String family = Bytes.toString(CellUtil.cloneFamily(cell));
                 String qualify = Bytes.toString(CellUtil.cloneQualifier(cell));
                 String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
                 String value = Bytes.toString(CellUtil.cloneValue(cell));
                 System.err.println(family+"_"+qualify+"_"+rowkey+"_"+value);
            }
        }

    }
  • 方法 4:根據rowkey和column獲取相應的資料
     public void getData() throws Exception{
        TableName tbname = TableName.valueOf("bd14:fromJava");
        Table table =connection.getTable(tbname);
        Get get = new Get(Bytes.toBytes("rowkey_"+i));
        Result result = table.get(get);
        //遍歷結果物件results
        for (Result result : results) {
        //巢狀遍歷result獲取cell
            for(Cell cell : result.listCells()){
            //使用CellUtil工具類直接獲取cell中的資料
                 String family = Bytes.toString(CellUtil.cloneFamily(cell));
                 String qualify = Bytes.toString(CellUtil.cloneQualifier(cell));
                 String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
                 String value = Bytes.toString(CellUtil.cloneValue(cell));
                 System.err.println(family+"_"+qualify+"_"+rowkey+"_"+value);
            }
        }

    }
  • 更新資料
    public void updateData(String tableName,String rowKey,String family, String columkey,String updatedata) throws Exception{
            //hbase中更新資料同樣採用put方法,在相同的位置put資料,則在查詢時只會返回時間戳較新的資料
            //且在檔案合併時會將時間戳較舊的資料捨棄
            Put put = new Put(Bytes.toBytes(rowKey));
            //將新資料新增到put中
            put.addColumn(Bytes.toBytes(family), Bytes.toBytes(columkey),Bytes.toBytes(updatedata));
            Table table = connection.getTable(TableName.valueOf(tableName));
            //將put寫入HBase
            table.put(put);
        }
  • 刪除資料
    //刪除某條記錄
    public void deleteData(String tableName,String rowKey,String family, String columkey) throws Exception{
        Table table = connection.getTable(TableName.valueOf(tableName));
        //建立delete物件
        Delete deletData= new Delete(Bytes.toBytes(rowKey));
        //將要刪除的資料的準確座標新增到物件中
        deletData.addColumn(Bytes.toBytes(family), Bytes.toBytes(columkey));
        //刪除表中資料
        table.delete(deletData);
    }

    //刪除一行資料
    public void deleteRow(String tableName,String rowKey) throws Exception{
        Table table = connection.getTable(TableName.valueOf(tableName));
        //通過行鍵刪除一整行的資料
        Delete deletRow= new Delete(Bytes.toBytes(rowKey));
        table.delete(deletRow);
    }