Java操作hbase的工具類

package com.ncs.dao;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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.TableName;
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.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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ncs.Conf;
import com.ncs.entity.DNResourceRecord;

/**
 * 操作Hbase的DAO
 * @author syl
 *
 */
@SuppressWarnings("deprecation")
public class HBaseDAO {  

    private static final Logger logger = LoggerFactory
            .getLogger(HBaseDAO.class);

    // 聲明靜態配置  
    private static Configuration conf = null;  
    private static HBaseAdmin admin = null;
    private volatile static HTable table = null;

    // 初始化靜態配置
    static {  
        conf = HBaseConfiguration.create();
        //使用eclipse時必須添加這個,否則無法定位   
        conf.set("hbase.zookeeper.quorum", Conf.get("zkConnect"));
        // 新建一個數據庫管理員 
        try {
            admin = new HBaseAdmin(conf);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    } 

    public HBaseDAO(String tableName) {
        try {
            table = new HTable(conf, tableName);
            //這裏默認值其實是64MB,所以應該改大一點比較好!
            table.setWriteBufferSize(1024 * 1024 * 10);
            // 並禁用hbase的自動提交功能
            table.setAutoFlushTo(false);
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }

    /**
     * 根據表名,判斷表是否存在
     * @param tableName     表名
     * @return  true 存在 ,false 不存在
     * @throws IOException
     */
    public static boolean tableExists(String tableName) throws IOException {
        // 判斷表是否存在
        boolean bool = admin.tableExists("emp");
        logger.info(tableName + " exists? " + bool);
        return bool;
    }

    /**
     * 創建數據庫表
     * @param tableName     表名
     * @param columnFamilys 列族名
     * @return  true 成功 ,false 失敗
     * @throws Exception
     */
    public boolean createTable(String tableName, String[] columnFamilys)  
            throws Exception {  

        boolean bool;
        // 判斷數據庫表是否存在
        if (admin.tableExists(tableName)) { 
            System.out.println("table " + tableName + " existed!!");  
            System.exit(0);  
            bool = false;
        } else {  
            // 新建一個表的描述  
            HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableName));
            // 在描述裏添加列族  
            for (String columnFamily : columnFamilys) {  
                HColumnDescriptor descriptor = new HColumnDescriptor(columnFamily);
                descriptor.setMaxVersions(10);
                tableDesc.addFamily(new HColumnDescriptor(descriptor));  
            }  
            // 根據配置好的描述建表  
            admin.createTable(tableDesc);  
            System.out.println("create table " + tableName + " success!");  
            bool = true;
        }  
        return bool;
    } 

    /**
     * 列出數據庫中所有表
     * @return 返回數據庫中所有表的描述的數組
     * @throws IOException
     */
    public HTableDescriptor[] showTables() throws IOException {

        // 獲取數據庫中表的集合
        HTableDescriptor[] tableDescriptor = admin.listTables();

        // 遍歷打印所有表名
        for (int i = 0; i < tableDescriptor.length; i++ ){
            System.out.println(tableDescriptor[i].getNameAsString());
        }
        return tableDescriptor;
    }

    /**
     * 根據表名,獲取數據庫表的列族信息
     * @param tableName     表名
     * @throws IOException
     */
    public void tableDetail(String tableName) throws IOException {

        HTableDescriptor tableDescriptor = admin.getTableDescriptor(Bytes.toBytes(tableName));  

        // 獲取數據庫表的名稱
        byte[] name = tableDescriptor.getName();  
        System.out.println("result:");  

        System.out.println("table name: " + new String(name)); 
        // 獲取數據庫表的列族名稱
        HColumnDescriptor[] columnFamilies = tableDescriptor.getColumnFamilies();  
        for(HColumnDescriptor d : columnFamilies){  
            System.out.println("column Families: " + d.getNameAsString());  
        }
    }

    /**
     * 添加一列族到現有的表
     * @param tableName     表名
     * @param coloumn       列族名
     * @throws IOException
     */
    public static void addColoumn(String tableName, String coloumn) throws IOException {

        // 初始化columnDescriptor對象
        HColumnDescriptor columnDescriptor = new HColumnDescriptor(coloumn);

        // 添加一個列族
        admin.addColumn(tableName, columnDescriptor);
        System.out.println("added " + coloumn + " to " + tableName);
    }

    /**
     * 刪除一列族從現有的表
     * @param tableName     表名
     * @param coloumn       列族名
     * @throws IOException
     */
    public static void deleteColoumn(String tableName, String coloumn) throws IOException {

        // 刪除一個列族
        admin.deleteColumn(tableName, coloumn);
        System.out.println("delete " + coloumn + " from " + tableName); 
    }

    /**
     * 根據表名,禁用數據庫表
     * @param tableName     表名
     * @throws IOException
     */
    public static void disableTable(String tableName) throws IOException {

        // 判斷數據庫表是否被禁用
        Boolean bool = admin.isTableDisabled(tableName);
        System.out.println(bool);

        // 禁用這張表
        if(!bool){
            admin.disableTable(tableName);
            System.out.println("Table:" + tableName + "disabled");
       }
    }

    /**
     * 根據表名,禁用並刪除數據庫表
     * @param tableName     表名
     * @throws Exception
     */
    public void deleteTable(String tableName) throws Exception {  

        if (admin.tableExists(tableName)) {  
            // 禁用一個表  
            admin.disableTable(tableName);  
            // 刪除表
            admin.deleteTable(tableName);  
            System.out.println("delete table " + tableName + " success!");  
        } else {  
            System.out.println("delete tabled failed! " + tableName + " not exists!");  
            System.exit(0);  
        }  
    } 

    /**
     * 添加一條數據 
     * @param tableName     表名
     * @param row           行名
     * @param columnFamily  列族名
     * @param column        列名
     * @param value         值
     * @throws Exception
     */
    public void addRow(String tableName, String row,  
            String columnFamily, String column, String value) throws Exception {  

        // 指定行  
        Put put = new Put(Bytes.toBytes(row));
        // 參數分別:列族、列、值  
        put.add(Bytes.toBytes(columnFamily), Bytes.toBytes(column), Bytes.toBytes(value));  
        table.put(put);  
//        logger.info("add " + columnFamily + ":" + column + ":" + value + " success!");
    }  

    /**
     * 批量插入
     * @param row           行名      需要變化
     * @param columnFamily  列族
     * @param set           值       一直變化
     * @throws Exception
     */
    public void addRows(List<String> row, String columnFamily, List<String> set) throws Exception {

        Put put = null;
        String columns = null;
        for (int i = 0; i < set.size(); i++) { 

            switch (i % 7) {
                case 0 : columns = "ttl"; break;
                case 1 : columns = "clazz"; break;
                case 2 : columns = "type"; break;
                case 3 : columns = "rdata"; break;
                case 4 : columns = "ispId"; break;
                case 5 : columns = "version"; break;
                case 6 : columns = "owner"; break;
            }

            put = new Put(Bytes.toBytes( row.get((int)(i / 7)) ) );// 設置rowkey 
            put.add(Bytes.toBytes(columnFamily), Bytes.toBytes(columns), Bytes.toBytes(set.get(i)));
            table.put(put);
        }
        table.close();
    }

    /**
     * 根據表名、列族名、列名,更新表中的某一列
     * @param tableName     表名
     * @param rowKey
     * @param familyName    列族名
     * @param columnName    列名
     * @param value         更新後的值
     * @throws IOException
     */
    public static void updateTable(String tableName, String rowKey,
            String familyName, String columnName, String value)
            throws IOException {

        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!");
    }

    /**
     * 爲表添加數據(適合知道有多少列族的固定表)
     * @param rowKey        
     * @param tableName     表名
     * @param column1       第一個列族列表
     * @param value1        第一個列的值的列表
     * @param column2       第二個列族列表
     * @param value2        第二個列的值的列表
     * @throws IOException
     */
    public static void addData(String rowKey, String tableName,
            String[] column1, String[] value1, String[] column2, String[] value2)
            throws IOException {

        // 設置rowkey
        Put put = new Put(Bytes.toBytes(rowKey));
        // 獲取所有的列族
        HColumnDescriptor[] columnFamilies = table.getTableDescriptor().getColumnFamilies();

        for (int i = 0; i < columnFamilies.length; i++) {
             // 獲取列族名
            String familyName = columnFamilies[i].getNameAsString();
            // article列族put數據
            if (familyName.equals("article")) { 
                for (int j = 0; j < column1.length; j++) {
                    put.add(Bytes.toBytes(familyName),
                            Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j]));
                }
            }
            // author列族put數據
            if (familyName.equals("author")) { 
                for (int j = 0; j < column2.length; j++) {
                    put.add(Bytes.toBytes(familyName),
                            Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j]));
                }
            }
        }
        table.put(put);
        System.out.println("add data Success!");
    }

    /**
     * 根據表名、行名,刪除一條(行)數據  
     * @param tableName     表名
     * @param row           行名
     * @throws Exception
     */
    public void deleteRow(String tableName, String row) throws Exception {  

        Delete del = new Delete(Bytes.toBytes(row));  
        table.delete(del);  
    }  

    /**
     * 根據表名、行名、列族名、列名刪除指定的列
     * @param tableName     表名
     * @param rowKey        行名
     * @param falilyName    列族名
     * @param columnName    列名
     * @throws IOException
     */
    public static void deleteColumn(String tableName, String rowKey,
            String falilyName, String columnName) throws IOException {

        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!");
    }

    /**
     * 根據表名、行名的數組。刪除多條數據  
     * @param tableName     表名
     * @param rows          行名的數組
     * @throws Exception
     */
    public void delMultiRows(String tableName, String[] rows)  
            throws Exception {  

        List<Delete> delList = new ArrayList<Delete>();  
        for (String row : rows) {  
            Delete del = new Delete(Bytes.toBytes(row));  
            delList.add(del);  
        }  
        table.delete(delList);  
    }  

    /**
     * 根據表名、行名,獲取一條數據
     * @param tableName     表名
     * @param row           行名
     * @throws Exception
     */
    public void getRow(String tableName, String row) throws Exception { 

        Get get = new Get(Bytes.toBytes(row));  
        Result result = table.get(get);  
        // 輸出結果,raw方法返回所有keyvalue數組  
        for (KeyValue rowKV : result.raw()) {  
            System.out.print("表名:" + tableName + " ");
            System.out.print("列族名:" + new String(rowKV.getFamily()) + " ");  
            System.out.print("行名:" + new String(rowKV.getRow()) + " ");  
            System.out.print("時間戳:" + rowKV.getTimestamp() + " ");  
            System.out.print("列名:" + new String(rowKV.getQualifier()) + " ");  
            System.out.println("值:" + new String(rowKV.getValue()));  
        }  
    } 

    /**
     * 根據表名、行名、列族名、列名,查詢某列數據的多個版本
     * @param tableName      表名
     * @param rowKey        行名
     * @param familyName    列族名
     * @param columnName    列名
     * @throws IOException
     */
    public void getResultByVersion(String tableName, String rowKey,
            String familyName, String columnName) throws IOException {

        Get get = new Get(Bytes.toBytes(rowKey));
        // 設置一次性獲取所有版本
        get.setMaxVersions(); 
        get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName));
        Result result = table.get(get);
        for (KeyValue kv : result.list()) {
            System.out.print("表名:" + tableName + " ");
            System.out.print("行名:" + rowKey + " ");
            System.out.print("列族名:" + new String(kv.getFamily()) + " ");  
            System.out.print("列名:" + new String(kv.getQualifier()) + " ");
            System.out.print("值:" + new String(kv.getValue()) + " ");
            System.out.println("時間戳:" + kv.getTimestamp() + " "); 
        }
    }

    /**
     * 根據表名、列名、列族名、列名查詢表中的某一列
     * @param tableName     表名
     * @param rowKey        行名
     * @param familyName    列族名
     * @param columnName    列名
     * @throws IOException
     */
    public static void getRowsByColumn(String tableName, String rowKey,
            String familyName, String columnName) throws IOException {

        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.print("表名:" + tableName + " ");
            System.out.print("列族名:" + new String(kv.getFamily()) + " ");  
            System.out.print("行名:" + new String(kv.getRow()) + " ");  
            System.out.print("時間戳:" + kv.getTimestamp() + " ");  
            System.out.print("列名:" + new String(kv.getQualifier()) + " ");  
            System.out.println("值:" + new String(kv.getValue()));  
        }
    }

    /**
     * 遍歷查詢hbase表start_rowkey到stop_rowkey之間的數據
     * @param tableName     表名
     * @param start_rowkey  開始的rowkey
     * @param stop_rowkey   結束的rowkey
     * @throws IOException
     */
    public static ResultScanner getRangeRows(String tableName, String startrow,
            String endrow) throws Exception {

        Scan s = new Scan(Bytes.toBytes(startrow), Bytes.toBytes(endrow));
        // 一次next()返回10列Result實例
//      s.setBatch(10);
        ResultScanner rs = table.getScanner(s);
        return rs;
    }

    /**
     * 根據表名,獲取所有的數據
     * @param tableName     表名
     * @throws Exception
     */
    public void getAllRows(String tableName) throws Exception { 

        Scan scan = new Scan();  
        // 設置緩存大小
        scan.setCaching(100);
        // 一次next()返回Result實例的列數,防止超過客戶端進程的內存容量
        scan.setBatch(6);
        ResultScanner results = table.getScanner(scan);  
        // 輸出結果  
        for (Result result : results) {  
            for (KeyValue rowKV : result.raw()) {  
                System.out.print("表名:" + tableName + " ");  
                System.out.print("列族名:" + new String(rowKV.getFamily()) + " ");  
                System.out.print("行名:" + new String(rowKV.getRow()) + " ");  
                System.out.print("時間戳:" + rowKV.getTimestamp() + " ");  
                System.out.print("列名:" + new String(rowKV.getQualifier()) + " ");  
                System.out.println("值:" + new String(rowKV.getValue()));  
            }  
        }  
    }  

    /**
     * 釋放HTable的所有資源
     * @throws IOException
     */
    public static void closeTbale() throws IOException {

        if (table != null) {
            table.close();
        }
        System.out.println("close table!");
    }

    /**
     * 將DNResourceRecord對象保存到HBase中
     * @param dnResourceRecords     對象集合
     * @param tableName             表名
     * @param columnFamily          列族名
     */
    public static void intoHbase(List<DNResourceRecord> dnResourceRecords, 
            String tableName, String columnFamily) {

        HBaseDAO hBaseDAO = new HBaseDAO(tableName);
        ArrayList<String> rows = new ArrayList<String>();   // rowKey
        ArrayList<String> set = new ArrayList<String>();    // value
        String rowKey;

        try {
            // 將集合對象存入hbase中
            for (DNResourceRecord dnResourceRecord : dnResourceRecords) {
                rowKey = dnResourceRecord.getRowKey();
                rows.add(rowKey);
                set.add(dnResourceRecord.getTtl().toString());
                set.add(dnResourceRecord.getClazz());
                set.add(dnResourceRecord.getType());
                set.add(dnResourceRecord.getRdata());
                set.add(dnResourceRecord.getIspId());
                set.add(dnResourceRecord.getVersion().toString());
                set.add(dnResourceRecord.getOwner());
            }
            hBaseDAO.addRows(rows, columnFamily, set);
            logger.info(dnResourceRecords.size() + " row dNResourceRecord has inesrt into hbase!");
        } catch(Exception e) {
            logger.error(" inesrt into hbase error! " + e.toString());
            e.printStackTrace();
        }
    }

    // 主函數  
    public static void main(String[] args) {  
        HBaseDAO hBaseDAO = new HBaseDAO("records");
        try {  
//            String tableName = "records";  
//            // 第一步:創建數據庫表:“student”  
//            String[] columnFamilys = { "info"};  
//            hBaseDAO.createTable(tableName, columnFamilys);  
//            // 第二步:向數據表的添加數據  
//            // 添加第一行數據  
//            if (tableExists(tableName)) { 
//              hBaseDAO.addRow(tableName, "zpc", "info", "age", "20");  
//              hBaseDAO.addRow(tableName, "zpc", "info", "sex", "boy");  
//              hBaseDAO.addRow(tableName, "zpc", "course", "china", "97");  
//              hBaseDAO.addRow(tableName, "zpc", "course", "math", "128");  
//                hBaseDAO.addRow(tableName, "zpc", "course", "english", "85");  
//                // 添加第二行數據  
//                hBaseDAO.addRow(tableName, "henjun", "info", "age", "19");  
//                hBaseDAO.addRow(tableName, "henjun", "info", "sex", "boy");  
//                hBaseDAO.addRow(tableName, "henjun", "course", "china","90");  
//                hBaseDAO.addRow(tableName, "henjun", "course", "math","120");  
//                hBaseDAO.addRow(tableName, "henjun", "course", "english","90");  
//                // 添加第三行數據  
//                hBaseDAO.addRow(tableName, "niaopeng", "info", "age", "18");
//                hBaseDAO.addRow(tableName, "niaopeng", "info", "sex","girl"); 
//                hBaseDAO.addRow(tableName, "niaopeng", "course", "china","100"); 
//                hBaseDAO.addRow(tableName, "niaopeng", "course", "math","100");  
//                hBaseDAO.addRow(tableName, "niaopeng", "course", "english","99");  
//                // 第三步:獲取一條數據  
//                System.out.println("**************獲取一條(zpc)數據*************");  
//                hBaseDAO.getRow(tableName, "zpc");  
//                // 第四步:獲取所有數據  
//                System.out.println("**************獲取所有數據***************");  
//                hBaseDAO.getAllRows(tableName);  
//  
//                // 第五步:刪除一條數據  
//                System.out.println("************刪除一條(zpc)數據************");
//                hBaseDAO.deleteRow(tableName, "zpc");  
//                hBaseDAO.getAllRows(tableName);
//                // 第六步:刪除多條數據  
//                System.out.println("**************刪除多條數據***************");  
//                String rows[] = new String[] { "qingqing","xiaoxue" };  
//                hBaseDAO.delMultiRows(tableName, rows);  
//                hBaseDAO.getAllRows(tableName);  
//                // 第七步:刪除數據庫  
//                System.out.println("***************刪除數據庫表**************");  
//                hBaseDAO.deleteTable("records");  
//                System.out.println("表"+tableName+"存在嗎?"+tableExists(tableName));  
//            } else {  
//                System.out.println(tableName + "此數據庫表不存在!");  
//            }  

//            hBaseDAO.showTables();
//            hBaseDAO.deleteTable("records");
//          String[] fam = new String[]{"info"};
//          hBaseDAO.createTable("records", fam);
//          System.out.println("*******************獲取表的信息*****************");
//          hBaseDAO.tableDetail("records");
//          System.out.println("*******************獲取表中某一條數據*****************");
//          hBaseDAO.getRow("records", "sex2.tld.");
//          System.out.println("=====================數據的多個版本===================");
//          hBaseDAO.getResultByVersion("records", "sina.com.cn.", "info", "rdata");
//          
//          // 第五步:刪除一條數據  
//          System.out.println("************刪除一條(zpc)數據************");
//          hBaseDAO.deleteRow("records", "乾杯.tld.");  
//              
//          System.out.println("=====================數據的多個版本===================");
//          hBaseDAO.getResultByVersion("records", "乾杯.tld.www2", "info", "rdata");
            System.out.println("*******************獲取數據庫中所有數據*****************");
            hBaseDAO.getAllRows("records");
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {
            try {
                HBaseDAO.closeTbale();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

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