HBase是一個分佈式的、面向列的開源數據庫,該技術來源於 Fay Chang 所撰寫的Google論文“Bigtable:一個結構化數據的分佈式存儲系統”。就像Bigtable利用了Google文件系統(File System)所提供的分佈式數據存儲一樣,HBase在Hadoop之上提供了類似於Bigtable的能力。HBase是Apache的Hadoop項目的子項目。HBase不同於一般的關係數據庫,它是一個適合於非結構化數據存儲的數據庫。另一個不同的是HBase基於列的而不是基於行的模式。
HBase 表一般特點:
1)大:一個表可以有上億行,上百萬列
2)面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索
3)稀疏:對於爲空(null)的列並不佔用存儲空間,表可以設計非常稀疏
Java 調用 Hbase 非關係型數據庫,Hbase 中提供了相關的 Java API 訪問接口便於使用,下面是本人綜合網絡總結的通過 Java 操作 HBase 進行創建、修改、刪除表以及查詢等。具體封裝代碼如下:
package yoodb.hbase; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.HTablePool; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.util.Bytes; public class HBaseTest { // 聲明靜態配置 static Configuration conf = null; static final HTablePool tablePool; static { conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "yoodb"); tablePool = new HTablePool(conf, 15); } /* * 創建表 * @tableName 表名 * @family 列族數組 */ public static void creatTable(String tableName, String[] family) throws Exception { HBaseAdmin admin = new HBaseAdmin(conf); HTableDescriptor desc = new HTableDescriptor(tableName); for (int i = 0; i < family.length; i++) { desc.addFamily(new HColumnDescriptor(family[i])); } if (admin.tableExists(tableName)) { System.out.println("table Exists!"); System.exit(0); } else { admin.createTable(desc); System.out.println("create table Success!"); } } /* * 表添加數據 * @rowKey rowKey * @tableName 表名 * @column1 第一個列族數組 realname * @value1 第一個列的值的數組 * @column2 第二個列族數組 address * @value2 第二個列的值的數組 */ public static void addTableData(String rowKey, String tableName,String[] column1, String[] value1, String[] column2, String[] value2) throws IOException { Put put = new Put(Bytes.toBytes(rowKey)); HTable table = (HTable) tablePool.getTable(tableName); HColumnDescriptor[] columnFamilies = table.getTableDescriptor() .getColumnFamilies(); for (int i = 0; i < columnFamilies.length; i++) { String familyName = columnFamilies[i].getNameAsString(); if (familyName.equals("realname")) { for (int j = 0; j < column1.length; j++) { put.add(Bytes.toBytes(familyName),Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j])); } } if (familyName.equals("address")) { for (int j = 0; j < column2.length; j++) { put.add(Bytes.toBytes(familyName),Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j])); } } } table.put(put); } /* * 更新表中的某一列 * @tableName 表名 * @rowKey rowKey * @familyName 列族名 * @columnName 列名 * @value 更新後的值 */ public static void updateTable(String tableName, String rowKey, String familyName, String columnName, String value) throws IOException { HTable table = (HTable) tablePool.getTable(tableName); Put put = new Put(Bytes.toBytes(rowKey)); put.add(Bytes.toBytes(familyName), Bytes.toBytes(columnName),Bytes.toBytes(value)); table.put(put); System.out.println("update table Success!"); } /* * 根據rwokey查詢 * @rowKey rowKey * @tableName 表名 */ public static Result getResult(String tableName, String rowKey) throws IOException { Get get = new Get(Bytes.toBytes(rowKey)); HTable table = (HTable) tablePool.getTable(tableName); Result result = table.get(get); for (KeyValue kv : result.list()) { System.out.println("family==>" + Bytes.toString(kv.getFamily())); System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier())); System.out.println("value==>" + Bytes.toString(kv.getValue())); System.out.println("Timestamp==>" + kv.getTimestamp()); } return result; } /* * 遍歷查詢hbase表數組 * @tableName 表名 */ public static void getResultScann(String tableName) throws IOException { Scan scan = new Scan(); ResultScanner rs = null; HTable table = (HTable) tablePool.getTable(tableName); try { rs = table.getScanner(scan); for (Result r : rs) { for (KeyValue kv : r.list()) { System.out.println("family==>" + Bytes.toString(kv.getFamily())); System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier())); System.out.println("value==>" + Bytes.toString(kv.getValue())); System.out.println("timestamp==>" + kv.getTimestamp()); } } } finally { rs.close(); } } /* * 查詢表中的某單一列 * @tableName 表名 * @rowKey rowKey */ public static void getResultByColumn(String tableName, String rowKey, String familyName, String columnName) throws IOException { HTable table = (HTable) tablePool.getTable(tableName); Get get = new Get(Bytes.toBytes(rowKey)); get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); // 獲取指定列族以及列中修飾符對應列名 Result result = table.get(get); for (KeyValue kv : result.list()) { System.out.println("family==>" + Bytes.toString(kv.getFamily())); System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier())); System.out.println("value==>" + Bytes.toString(kv.getValue())); System.out.println("Timestamp==>" + kv.getTimestamp()); } } /* * 查詢某列數據的多個版本 * @tableName 表名 * @rowKey rowKey * @familyName 列族名 * @columnName 列名 */ public static void getResultByVersion(String tableName, String rowKey, String familyName, String columnName) throws IOException { HTable table = (HTable) tablePool.getTable(tableName); Get get = new Get(Bytes.toBytes(rowKey)); get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); get.setMaxVersions(5); Result result = table.get(get); for (KeyValue kv : result.list()) { System.out.println("family==>" + Bytes.toString(kv.getFamily())); System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier())); System.out.println("value==>" + Bytes.toString(kv.getValue())); System.out.println("Timestamp==>" + kv.getTimestamp()); } } /* * 刪除指定的列 * @tableName 表名 * @rowKey rowKey * @familyName 列族名 * @columnName 列名 */ public static void deleteColumn(String tableName, String rowKey, String falilyName, String columnName) throws IOException { HTable table = (HTable) tablePool.getTable(tableName); Delete deleteColumn = new Delete(Bytes.toBytes(rowKey)); deleteColumn.deleteColumns(Bytes.toBytes(falilyName),Bytes.toBytes(columnName)); table.delete(deleteColumn); System.out.println(falilyName + "==>" + columnName + "is deleted!"); } /* * 刪除指定的列 * @tableName 表名 * @rowKey rowKey */ public static void deleteAllColumn(String tableName, String rowKey) throws IOException { HTable table = (HTable) tablePool.getTable(tableName); Delete deleteAll = new Delete(Bytes.toBytes(rowKey)); table.delete(deleteAll); System.out.println("all columns are deleted!"); } /* * 刪除表 * * @tableName 表名 */ public static void deleteTable(String tableName) throws IOException { HBaseAdmin admin = new HBaseAdmin(conf); admin.disableTable(tableName); admin.deleteTable(tableName); System.out.println(tableName + " is deleted!"); } }
Java Hbase main函數測試類,具體代碼如下:
package com.yoodb; public class Test { public static void main(String[] args) throws Exception { // 創建表 String tableName = "yoodbblog"; String[] family = { "realname","address" }; HBaseTest.creatTable(tableName,family); // 爲表添加數據 String[] column1 = { "title", "author", "content" }; String[] value1 = {"素文宅","yoodb","www.yoodb.com" }; String[] column2 = { "name", "nickname" }; String[] value2 = { "真實名稱", "暱稱" }; HBaseTest.addTableData("rowkey1","yoodbblog",column1, value1, column2, value2); // 刪除一列 HBaseTest.deleteColumn("yoodbblog", "rowkey1", "realname", "name"); // 刪除所有列 HBaseTest.deleteAllColumn("yoodbblog", "rowkey1"); // 刪除表 HBaseTest.deleteTable("yoodbblog"); // 查詢 HBaseTest.getResult("yoodbblog", "rowkey1"); // 查詢某一列的值 HBaseTest.getResultByColumn("yoodbblog", "rowkey1", "realname", "nickname"); // 修改某一列的值 HBaseTest.updateTable("yoodbblog", "rowkey1", "realname", "nickname","假暱稱"); // 遍歷表數據查詢 HBaseTest.getResultScann("yoodbblog"); // 查詢某列的多版本 HBaseTest.getResultByVersion("yoodbblog", "rowkey1", "realname", "name"); } }
來源:http://blog.yoodb.com/yoodb/article/detail/1092