201707121000复习-hbase篇-api使用篇

一、api分为admin api ,可以创建库,创建表等。还有client api,只可以增删改查表里面的数据,只有在client api里才会用到过滤器

package com.practice.practice2_hbase;

import java.io.IOException;

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
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.client.Table;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Before;
import org.junit.Test;

/**
 * hbase测试
 */
public class AppTest {

    Connection conn;   // 获取一张表,对表中记录进行增删改查
    Admin admin; // 对表本身进行增删改查

    /**
     * 获取连接和管理员
     * 通过连接可以获取一张表,然后对表中记录进行增删改查
     * 通过管理员可以对表或者库进行增删改查
     */
    @Before
    public void getConn() {
        try {
            // 通过连接获取table对象,可以进行相应查询
            conn = ConnectionFactory.createConnection(HBaseConfiguration.create());
            // 通过连接获取admin对象,可以进行相应增加或修改等
            admin = conn.getAdmin();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 表的增删改查--增
     * 
     * @throws Exception
     */
    @Test
    public void createTable() throws Exception {
        // 用管理员来创建表:指定表名
        HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("ns1:test1"));
        // 创建两个列族
        HColumnDescriptor cf1 = new HColumnDescriptor("cf1");
        HColumnDescriptor cf2 = new HColumnDescriptor("cf2");
        // 添加两个列族
        hTableDescriptor.addFamily(cf1);
        hTableDescriptor.addFamily(cf2);
        // 效果: crate 'ns1:test1',{NAME=>'cf1'},{NAME=>'cf2'} 或者 
        // create 'ns1:test1','cf1','cf2'
        admin.createTable(hTableDescriptor);
        admin.close();
    }

    /**
     * 表的增删改查--删
     * 
     * @throws Exception
     */
    @Test
    public void dropTable() throws Exception {
        admin.disableTable(TableName.valueOf("nst1:test1"));
        admin.deleteTable(TableName.valueOf("ns1:test1"));
        admin.close();
    }

    /**
     * 表的增删改查--改
     * 
     * @throws Exception
     */
    @Test
    public void alterTable() throws Exception {
        // 要想修改表就必须先禁用表,禁用表之后,就不能使用conn.getTable()方法来得到表了,因为已经得不到了。表的相关信息都是用admin然后指定表名得到的。
        admin.disableTable(TableName.valueOf("ns1:test1"));
        // 改1:增加一个新的列族cf3
        HTableDescriptor nowTableDesc = admin.getTableDescriptor(TableName.valueOf("ns1:test1"));
        nowTableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf3")));
        admin.modifyTable(TableName.valueOf("ns1:test1"), nowTableDesc);
        // 改2:修改列族cf3下列的保存版本数量
        HColumnDescriptor cf3 = admin.getTableDescriptor(TableName.valueOf("ns1:test1"))
                .getFamily(Bytes.toBytes("cf3"));
        cf3.setVersions(1, 5);
        admin.modifyColumn(TableName.valueOf("ns1:test1"), cf3);
        admin.enableTable(TableName.valueOf("ns1:test1"));
        // 改3:删除一个列族cf3
        nowTableDesc = admin.getTableDescriptor(TableName.valueOf("ns1:test1"));
        cf3 = nowTableDesc.getFamily(Bytes.toBytes("cf3"));
        System.out.println("最小版本:" + cf3.getMinVersions() + "\t最大版本:" + cf3.getMaxVersions());
        nowTableDesc.removeFamily(Bytes.toBytes("cf3"));
        admin.modifyTable(TableName.valueOf("ns1:test1"), nowTableDesc);
        admin.enableTable(TableName.valueOf("ns1:test1"));
    }

    /**
     * 表的增删改查--查
     * 
     * @throws Exception
     */
    @Test
    public void listTable() throws Exception {
        TableName[] listTableNames = admin.listTableNames();
        for (TableName table : listTableNames) {
            System.out.println(Bytes.toString(table.getName()));
        }
    }

    /**
     * 数据的增删盖改查 -- 增和改
     * 
     * @throws Exception
     */
    @Test
    public void insertData() throws Exception {
        HTable table = (HTable) (conn.getTable(TableName.valueOf("ns1:test1")));
        // 开启缓存插入
        table.setAutoFlush(false, true);
        // 循环生成put
        Put put = null;
        for (int i = 10000; i < 20000; i++) {
            put = new Put(Bytes.toBytes(i + ""));
            put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("age"), Bytes.toBytes(i + ""));
            put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("name"), Bytes.toBytes("tom" + i));
            put.addColumn(Bytes.toBytes("cf2"), Bytes.toBytes("age"), Bytes.toBytes(i + ""));
            put.addColumn(Bytes.toBytes("cf2"), Bytes.toBytes("name"), Bytes.toBytes("tomas" + i));
            table.put(put);
        }
        // 有一些会保留在缓存中,程序结束前,先刷新缓存
        table.flushCommits();
        table.close();
    }

    /**
     * 数据的增删改查 -- 查 -- 用scan查,且查指定startkey到endkey的数据内容,且带缓冲地查,且指定过滤器
     * 
     * @throws Exception
     * 
     */
    @Test
    public void getDataWithScan() throws Exception {
        Table table = conn.getTable(TableName.valueOf("ns1:test1"));
        // 定制扫描器
        Scan scan = new Scan(Bytes.toBytes("12345"), Bytes.toBytes("13456"));
        // 定制过滤器:需要传入比较的操作符,和比较器
        RowFilter rowFilter1 = new RowFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL,
                new BinaryComparator(Bytes.toBytes("13000")));
        RowFilter rowFilter2 = new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL,
                new BinaryComparator(Bytes.toBytes("13400")));
        // 把过滤器传递给扫描器:在扫描过程中过滤
        scan.setFilter(new FilterList(rowFilter1, rowFilter2));
        // 开启缓存查询,如果不设置这个值,那么默认值就是-1,即不缓存,等到遍历的时候,每次next()都会出发rpc,都会去regionserver上请求数据
        // 设置为非-1的值即开启缓存,并每次缓存指定值的行数。较少了网络传输,但是会增加内存压力。需要平衡考虑。
        scan.setCaching(100);

        // 开始扫描
        String row = null;
        Cell cell = null;
        ResultScanner scanner = table.getScanner(scan);
        for (Result res : scanner) {
            row = Bytes.toString(res.getRow());
            cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("age"));
            System.out.print(row + "\t" + "cf1:age=" + Bytes.toInt(cell.getValueArray()) + "\t");
            cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("name"));
            System.out.print(row + "\t" + "cf1:name=" + Bytes.toString(cell.getValueArray()) + "\t");
            cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("age"));
            System.out.print(row + "\t" + "cf2:age=" + Bytes.toInt(cell.getValueArray()) + "\t");
            cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("name"));
            System.out.println(row + "\t" + "cf2:name=" + Bytes.toString(cell.getValueArray()) + "\t");
        }
        table.close();
    }

    /**
     * 数据的增删盖改查 -- 查 -- 用get查指定的一行
     * 
     * @throws Exception
     * 
     */
    @Test
    public void getDataWithGet() throws Exception {
        Table table = conn.getTable(TableName.valueOf("ns1:test1"));
        // 定制扫描器
        Get get = new Get(Bytes.toBytes("13002"));
        Result result = table.get(get);
        Cell cell = result.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("age"));
        System.out.print(Bytes.toString(CellUtil.cloneValue(cell)) + "\t");
        cell = result.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("name"));
        System.out.print(Bytes.toString(CellUtil.cloneValue(cell)) + "\t");
        cell = result.getColumnLatestCell(Bytes.toBytes("cf2"), Bytes.toBytes("age"));
        System.out.print(Bytes.toString(CellUtil.cloneValue(cell)) + "\t");
        cell = result.getColumnLatestCell(Bytes.toBytes("cf2"), Bytes.toBytes("name"));
        System.out.println(Bytes.toString(CellUtil.cloneValue(cell)) + "\t");
        table.close();
    }

    /**
     * 数据的增删盖改查 -- 删
     * 
     * @throws Exception
     * 
     */
    @Test
    public void deletaData() throws Exception {
        Table table = conn.getTable(TableName.valueOf("ns1:test1"));
        Delete del = new Delete(Bytes.toBytes("13000"));
        del.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("age"));
        del.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("name"));
        table.delete(del);
        table.close();
    }

    /**
     * 测试复杂过滤器 where ((name like 't%') and (age > 20)) or ((name like '%t') and
     * (age < 20))
     * 
     * @throws Exception
     */
    @Test
    public void complexFilter() throws Exception {
        HTable table = (HTable) conn.getTable(TableName.valueOf("ns1:test1"));

        // 生成多个过滤器,然后拼装,   Q:能不能再hbase shell中使用过滤器?

        Scan scan = new Scan();
        ResultScanner scanner = table.getScanner(scan);
        for (Result res : scanner) {
            System.out.println(res);
        }
    }

}
View Code

 

二、过滤器

  1、接口及一些常用过滤器类,

    

  2、自定义过滤器

package com.practice.practice2_hbase;

import java.io.IOException;

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.filter.FilterBase;

public class MyFilter extends FilterBase {

    @Override
    public ReturnCode filterKeyValue(Cell v) throws IOException {
        /**
         * 输入一个Cell,从cell中得到它的value,然后判断是否过滤掉,然后返回值有一下几种 
         * return ReturnCode.INCLUDE; 
         * return ReturnCode.INCLUDE_AND_NEXT_COL; 
         * return ReturnCode.NEXT_COL; 
         * return ReturnCode.NEXT_ROW; 
         * return ReturnCode.SEEK_NEXT_USING_HINT; 
         * return ReturnCode.SKIP;
         */
        byte[] valueArray = v.getValueArray();
        String value = new String(valueArray);
        if(value.equals("hello")){
            return ReturnCode.INCLUDE;
        }else {
            return ReturnCode.SKIP;
        }
        

    }

}
View Code

 

posted @ 2017-09-04 17:13  IT豪哥  阅读(123)  评论(0编辑  收藏  举报