HBase CURD之Get

HBase CURD之Get

下面我們將介紹從客戶端API中獲取已存數據的方法。HTable類中提供了get()方法,同時還有與之對應的Get類。get方法分爲兩類:一類是一次獲取一行數據;另一類是一次獲取多行數據。

單行get

下面是示例代碼:

@Test
public void testGet() throws IOException {
    Connection conn = ConnectionFactory.createConnection();
    Table table = conn.getTable(TableName.valueOf("ns1:t1"));
    Get get = new Get(Bytes.toBytes("row93"));
    Result r = table.get(get);
    List<Cell> cells = r.listCells();
    for (Cell c : cells){
        String rowKey = Bytes.toString(CellUtil.cloneRow(c));
        String family = Bytes.toString(CellUtil.cloneFamily(c));
        String column = Bytes.toString(CellUtil.cloneQualifier(c));
        String value = Bytes.toString(CellUtil.cloneValue(c));

        System.out.println(rowKey + "," + family + "," + column + "," + value);
    }
}

從上面代碼可以看出,數據的查詢是通過Table的get方法獲取的,get方法對應着Get對象。下面看一下Get類的構造函數。

Get構造函數

public Get(byte [] row) // 指定rowKey
public Get(Get get)     // 從其他Get對象創建實例

Tip

雖然一次get操作只能讀取一行數據,但不會限制一行當中取多少列或者多少單元格。

與put操作一樣,用戶有許多方法可用,可以通過多種標準篩選目標數據,也可以指定精確的座標獲取某個單元格的數據:

Get addFamily(byte [] family)                   // 限制get請求只能取得一個制定的列族,要取得多個列族時需要多次調用。
Get addColumn(byte [] family,byte [] qualifier) // 用戶通過他可以指定get取得那一列的數據,從而進一步縮小地址空間。
Get setTimeRange(long minStamp,long maxStamp)   // 設置只能在制定的時間戳範圍獲得列版本。
Get setTimeStamp(long timestamp)                // 獲得帶有制定時間戳的列的版本。
Get setMaxVersions()                            // 設置最大版本數,設置爲最大版本數爲Integer的最大值。
Get setMaxVersions(int maxVersions)

addFamily()方法限制get請求只能取得一個指定的列族,要取得多次調用。addColumn()方法的使用與之類似,用戶通過它可以指定get取得哪一列的數據,從而進一步縮小地址空間。有一些方法允許用戶設定要獲取的數據的時間戳,或者通過設定一個時間段來取得時間戳屬於該時間段內的數據。

最後,如果用戶沒有設定時間戳的話,也有方法允許用戶設定要獲取的數據的版本數目。默認情況下,版本數爲1,即get方法請求返回最新的匹配版本。如果有疑問,可以使用getMaxVersions()來檢查這個Get實例所要取出的最大版本數。不帶參數的setMaxVersions()方法會把要取出的最大版本數設爲Integer.MAX_VALUE,這是用戶在單元格中所有的版本,換句話說,此時系統會返回用戶在列族中已配置的最大版本數以內的數據。

Get類中的其他常用方法

方法 描述
getRow() 返回創建Get實例時指定的行鍵
getTimeRange() 返回指定的Get實例的時間戳範圍
setFilter()/getFilter() 用戶可以使用該一個特定的過濾器實例,通過多種規則和條件來篩選列和單元格。
setCacheBlocks()/getCacheBlocks() 每個HBase的region服務器都有一個塊緩存來有效地保存最近存取過的數據,並以此來加速之後的相鄰信息的讀取。不過在某些情況下,例如完全隨機讀取時,最好能避免這種機制帶動的干擾。這些方法能夠控制檔次讀取的塊緩存機制是否起效。
numFamilies() 快捷地獲取列族FamilyMap大小的方法,包括用addFamily()方法和addColumn()方法添加的列族。
hasFamilies() 檢查列族或列是否存在於當前的Get實例中
familySet()/getFamilyMap() 這些方法能夠讓用戶直接訪問addFamily()和addColumn()添加的列族和列。FamilyMap列族中鍵是列族的名稱,鍵對應的值是指定列族的限定符列表。familySet()方法返回一個所有已存儲列族的Set,即一個只包含列族名的集合。

Result類

當用戶使用get()方法獲取數據時,HBase返回的結果包含所有匹配的單元格數據,這些數據將被封裝在一個Result實例中返回給用戶。用它提供的方法,可以從服務器端獲取匹配指定行的特定返回值,這些值包括列族、列限定符和時間戳等。常用方法如下:

byte[] getValue(byte[] family,byte[] qualifier) // 方法允許用戶取得一個HBase中存儲的特定單元格的值。因爲該方法不能指定時間戳,所以用戶只能獲取數據最新的版本。
byte [] value()                                 // 返回第一個列對應的最新單元格的值。
byte [] getRow()                                // 返回創建Get對象當前實例中的rowKey
int size()                                      // 返回Cell實例的數目
boolean isEmpty()                               // 查看鍵值對的數目是否大於0
Cell[] rawCells()                               // 返回的數組已經按照字典序排列;排序規則是先按列族排序,列族內再按列限定符排序,此後再按時間戳排序,最後按類型排序。
List<Cell> listCells()                          // 返回所有Cell對象的集合
List<Cell> getColumnCells(byte [] family, byte [] qualifier)  // 返回特定列的單元格
Cell getColumnLatestCell(byte [] family, byte [] qualifier)   // 返回最新版本的Cell對象
boolean containsColumn(byte [] family, byte [] qualifier)     // 檢查指定列的值是否存在

字典排序規則

排序規則是先按列族排序,列族內再按列限定符排序,此後再按時間戳排序,最後按類型排序。

Get列表

使用列表參數的get()方法與使用列表參數的put方法對應,用戶可以用一次請求獲取多行數據。它允許用戶快速高效的從遠程服務器獲取相關的或完全隨機的多行數據。

@Test
public void testGet2() throws IOException {
    Connection conn = ConnectionFactory.createConnection();
    Table table = conn.getTable(TableName.valueOf("ns1:t1"));
    List<Get> list = new ArrayList<Get>();
    Get get1 = new Get(Bytes.toBytes("row93"));
    Get get2 = new Get(Bytes.toBytes("row94"));
    Get get3 = new Get(Bytes.toBytes("row95"));
    list.add(get1);
    list.add(get2);
    list.add(get3);
    Result[] results = table.get(list);
    for (Result r : results){
        List<Cell> cells = r.listCells();
        for (Cell c : cells){
            String rowKey = Bytes.toString(CellUtil.cloneRow(c));
            String family = Bytes.toString(CellUtil.cloneFamily(c));
            String column = Bytes.toString(CellUtil.cloneQualifier(c));
            String value = Bytes.toString(CellUtil.cloneValue(c));

            System.out.println(rowKey + "," + family + "," + column + "," + value);
        }
    }
}

@Test
public void testGet3() throws IOException {
    Connection conn = ConnectionFactory.createConnection();
    Table table = conn.getTable(TableName.valueOf("ns1:t1"));
    List<Get> list = new ArrayList<Get>();
    Get get1 = new Get(Bytes.toBytes("row93"));
    Get get2 = new Get(Bytes.toBytes("row94"));
    Get get3 = new Get(Bytes.toBytes("row95"));
    list.add(get1);
    list.add(get2);
    list.add(get3);
    Result[] results = table.get(list);
    for (Result r : results){
        List<Cell> cellsId = r.getColumnCells(Bytes.toBytes("f1"),Bytes.toBytes("id"));
        for (Cell cid: cellsId) {
            int id = Bytes.toInt(CellUtil.cloneValue(cid));
            System.out.println(id);
        }
        List<Cell> cellsAges = r.getColumnCells(Bytes.toBytes("f1"),Bytes.toBytes("age"));
        for (Cell cage: cellsAges) {
            int age = Bytes.toInt(CellUtil.cloneValue(cage));
            System.out.println(age);
        }
        List<Cell> cellsNames = r.getColumnCells(Bytes.toBytes("f1"),Bytes.toBytes("name"));
        for (Cell cname : cellsNames) {
            String name = Bytes.toString(CellUtil.cloneValue(cname));
            System.out.println(name);
        }
    }
}


@Test
public void testGet4() throws IOException {
    Connection conn = ConnectionFactory.createConnection();
    Table table = conn.getTable(TableName.valueOf("ns1:t1"));
    List<Get> list = new ArrayList<Get>();
    Get get1 = new Get(Bytes.toBytes("row93"));
    Get get2 = new Get(Bytes.toBytes("row94"));
    Get get3 = new Get(Bytes.toBytes("row95"));
    list.add(get1);
    list.add(get2);
    list.add(get3);
    Result[] results = table.get(list);
    for (Result r : results){
        Cell cellsId = r.getColumnLatestCell(Bytes.toBytes("f1"),Bytes.toBytes("id"));
        int id = Bytes.toInt(CellUtil.cloneValue(cellsId));
        System.out.println(id);

        Cell cellsAge = r.getColumnLatestCell(Bytes.toBytes("f1"),Bytes.toBytes("age"));
        int age = Bytes.toInt(CellUtil.cloneValue(cellsAge));
        System.out.println(age);

        Cell cellsName = r.getColumnLatestCell(Bytes.toBytes("f1"),Bytes.toBytes("name"));
        String name = Bytes.toString(CellUtil.cloneValue(cellsName));
        System.out.println(name);

    }
}

獲取數據的其他方法

boolean exists(Get get)             // 測試表中的列是否存在。如果存在返回true,這是一個服務器端調用,防止任何數據轉移到客戶端。
boolean[] existsAll(List<Get> gets) // 與上面方法功能類似,只不過返回的是boolean數組

Tip

exists()和existsAll()方法會引發regionServer端查詢數據的操作,包括加載文件塊來檢查某行或某列是否存在。用戶通過這種方法只能避免網絡數據傳輸的開銷,不過在需要檢查或頻繁檢查一個比較大的列時,這種方法還是十分實用的。

參考文獻

HBase權威指南

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章