一篇文章入门 HBase 的 Java API

前言

本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系

正文

  • 这里为了方便测试代码,使用junit进行测试。

1、初始化一个init方法

public class TestHbase {

        //声明一个Configuration对象
        private Configuration conf=null;
        //声明一个hbase数据库连接
        private Connection conn = null;
       
        @Before
        public void init() throws Exception{
conf= HBaseConfiguration.create();
  
 // 对于hbase的客户端来说,只需要知道hbase所使用的zookeeper集群地址就可以了
       conf.set("hbase.zookeeper.quorum","node1:2181,node2:2181,node3:2181");

//获取链接
conn= ConnectionFactory.createConnection(conf);
        
	}
}    
    

2、创建一个表

        /**
         * 建表
         * @throws Exception
         *  hbase shell------> create 'tableName','列族1','列族2'
         */
        @Test
        public void createTable() throws Exception{
            //获取一个表的管理器
            Admin admin = conn.getAdmin();
            //构造一个表描述器,并指定表名
            HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf("t_user_info".getBytes()));
            //构造一个列族描述器,并指定列族名
            HColumnDescriptor hcd1 = new HColumnDescriptor("base_info");
            // 构造第二个列族描述器,并指定列族名
            HColumnDescriptor hcd2 = new HColumnDescriptor("extra_info");
            // 为该列族设定一个版本数量
            hcd2.setVersions(1, 3);

            // 将列族描述器添加到表描述器中
            tableDescriptor.addFamily(hcd1).addFamily(hcd2);

            //利用表的管理器创建表
            admin.createTable(tableDescriptor);
            //关闭
            admin.close();
            conn.close();
        }

3、修改表属性

		/**
         * 修改表
         * @throws Exception
         */   //hbase shell   alter 't_user_info' ,'base_info',
              //   alter 't1', NAME => 'f1', VERSIONS => 5
        @Test
        public void modifyTable() throws Exception{
            //获取一个表的管理器
            Admin admin = conn.getAdmin();
            //获取表的描述器
            HTableDescriptor tableDescriptor = admin.getTableDescriptor(TableName.valueOf("t_user_info"));
            //修改已有的ColumnFamily---extra_info最小版本数和最大版本数
            HColumnDescriptor hcd1 = tableDescriptor.getFamily("extra_info".getBytes());
            hcd1.setVersions(2,5);

            // 添加新的ColumnFamily
            tableDescriptor.addFamily(new HColumnDescriptor("other_info"));

            //表的管理器admin 修改表
            admin.modifyTable(TableName.valueOf("t_user_info"),tableDescriptor);
            //关闭
            admin.close();
            conn.close();
        }

4、put添加数据

/**
         *  put添加数据
         * @throws Exception     hbase shell  put 't_user_info','rk00001','base_info:name','lisi'
         */
        @Test
        public void testPut() throws Exception {
            //构建一个 table对象,通过table对象来添加数据
            Table table = conn.getTable(TableName.valueOf("t_user_info"));
            //创建一个集合,用于存放Put对象
            ArrayList<Put> puts = new ArrayList<Put>();

            // 构建一个put对象(kv),指定其行键  例如hbase shell:  put '表名','rowkey','列族:列名称','值'
            Put put01 = new Put(Bytes.toBytes("user001"));  // "user001".getBytes()
            put01.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("zhangsan"));

            Put put02 = new Put("user001".getBytes());
            put02.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("password"), Bytes.toBytes("123456"));

            Put put03 = new Put("user002".getBytes());
            put03.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("lisi"));
            put03.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("married"), Bytes.toBytes("false"));

            Put put04 = new Put("zhang_sh_01".getBytes());
            put04.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("zhang01"));
            put04.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("married"), Bytes.toBytes("false"));

            Put put05 = new Put("zhang_sh_02".getBytes());
            put05.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("zhang02"));
            put05.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("married"), Bytes.toBytes("false"));

            Put put06 = new Put("liu_sh_01".getBytes());
            put06.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("liu01"));
            put06.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("married"), Bytes.toBytes("false"));

            Put put07 = new Put("zhang_bj_01".getBytes());
            put07.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("zhang03"));
            put07.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("married"), Bytes.toBytes("false"));

            Put put08 = new Put("zhang_bj_01".getBytes());
            put08.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("zhang04"));
            put08.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("married"), Bytes.toBytes("false"));
            put08.setDurability(Durability.SYNC_WAL);
            //把所有的put对象添加到一个集合中
            puts.add(put01);
            puts.add(put02);
            puts.add(put03);
            puts.add(put04);
            puts.add(put05);
            puts.add(put06);
            puts.add(put07);
            puts.add(put08);

            //一起提交所有的记录
            table.put(puts);


            table.close();
            conn.close();

        }

5、scan 查询单条数据

        /**
         *  读取数据  get:一次读一行
         * @throws Exception       
         *   hbase shell  :     get 't_user_info',"rowkey"
         */
        @Test
        public void testGet() throws Exception {
            //获取一个table对象
            Table table = conn.getTable(TableName.valueOf("t_user_info"));

            // 构造一个get查询参数对象,指定要get的是哪一行
            Get get = new Get("user001".getBytes());
            //返回查询结果数据
            Result result = table.get(get);
            //获取结果中的所有cell
            List<Cell> cells = result.listCells();
            //遍历所有的cell
            for(Cell c:cells){
				//获取行键
                byte[] rowBytes = CellUtil.cloneRow(c);
                //获取列族
                byte[] familyBytes = CellUtil.cloneFamily(c);
                //获取列族下的列名称
                byte[] qualifierBytes = CellUtil.cloneQualifier(c);
                //列字段的值
                byte[] valueBytes = CellUtil.cloneValue(c);
                
                System.out.print(new String(rowBytes)+" ");
                System.out.print(new String(familyBytes)+":");
                System.out.print(new String(qualifierBytes)+" ");
                System.out.println(new String(valueBytes));

            }

            //关闭
            table.close();
            conn.close();

        }

6、scan 批量查询数据

        /**
         * scan 批量查询数据
         * @throws Exception   hbase shell  scan 't_user_info'
         */
        @Test
        public void testScan() throws Exception {
            //获取table对象
            Table table = conn.getTable(TableName.valueOf("t_user_info"));
            //获取scan对象
            Scan scan = new Scan();
            //获取查询的数据
            ResultScanner scanner = table.getScanner(scan);
            //获取ResultScanner所有数据,返回迭代器
            Iterator<Result> iter = scanner.iterator();
            //遍历迭代器
            while (iter.hasNext()) {
                //获取当前每一行结果数据
                Result result = iter.next();
                //获取当前每一行中所有的cell对象
                List<Cell> cells = result.listCells();
                //迭代所有的cell
                for(Cell c:cells){
                    //获取行键
                    byte[] rowBytes = CellUtil.cloneRow(c);
                    //获取列族
                    byte[] familyBytes = CellUtil.cloneFamily(c);
                    //获取列族下的列名称
                    byte[] qualifierBytes = CellUtil.cloneQualifier(c);
                    //列字段的值
                    byte[] valueBytes = CellUtil.cloneValue(c);

                    System.out.print(new String(rowBytes)+" ");
                    System.out.print(new String(familyBytes)+":");
                    System.out.print(new String(qualifierBytes)+" ");
                    System.out.println(new String(valueBytes));
                }
                System.out.println("-----------------------");
            }

            //关闭
            table.close();
            conn.close();

        }

7、delete删除表中的列数据

       /**
        * 删除表中的列数据
        * @throws Exception     
        * hbase shell  delete 't_user_info','user001','base_info:password'
        */
        @Test
        public void testDel() throws Exception {
            //获取table对象
            Table table = conn.getTable(TableName.valueOf("t_user_info"));
            //获取delete对象,需要一个rowkey
            Delete delete = new Delete("user001".getBytes());
            //在delete对象中指定要删除的列族-列名称
        delete.addColumn("base_info".getBytes(), "password".getBytes());
            //执行删除操作
            table.delete(delete);

            //关闭
            table.close();
            conn.close();
        }

8、删除表

       /**
         * 删除表
         * @throws Exception   
         * hbase shell   先disable 't_user_info'   然后drop 't_user_info'
         */
        @Test
        public void testDrop() throws Exception {
            //获取一个表的管理器
            Admin admin = conn.getAdmin();
            //删除表时先需要disable,将表置为不可用,然后在delete
            admin.disableTable(TableName.valueOf("t_user_info"));
            admin.deleteTable(TableName.valueOf("t_user_info"));
            admin.close();
            conn.close();
    }

9、过滤器的使用

  • 过滤器的类型很多,但是可以分为两大类——比较过滤器专用过滤器
  • 过滤器的作用是在服务端判断数据是否满足条件,然后只将满足条件的数据返回给客户端

9.1 hbase过滤器的比较运算符

LESS  <
LESS_OR_EQUAL <=
EQUAL =
NOT_EQUAL <>
GREATER_OR_EQUAL >=
GREATER >

9.2 hbase过滤器的比较器(指定比较机制)

BinaryComparator  按字节索引顺序比较指定字节数组
BinaryPrefixComparator 跟前面相同,只是比较左端的数据是否相同
NullComparator 判断给定的是否为空
BitComparator 按位比较
RegexStringComparator 提供一个正则的比较器,仅支持 EQUAL 和非EQUAL
SubstringComparator 判断提供的子串是否出现在value中。


9.3 过滤器使用实战

9.3.1 针对行键的前缀过滤器
  • PrefixFilter
public void testFilter1() throws Exception {

// 针对行键的前缀过滤器
  Filter pf = new PrefixFilter(Bytes.toBytes("liu"));//"liu".getBytes()
  testScan(pf);
}

     //定义一个方法,接受一个过滤器,返回结果数据
public void testScan(Filter filter) throws Exception {
        Table table = conn.getTable(TableName.valueOf("t_user_info"));

        Scan scan = new Scan();
        //设置过滤器
        scan.setFilter(filter);

        ResultScanner scanner = table.getScanner(scan);
        Iterator<Result> iter = scanner.iterator();
        //遍历所有的Result对象,获取结果
        while (iter.hasNext()) {
            Result result = iter.next();
            List<Cell> cells = result.listCells();
            for (Cell c : cells) {
                //获取行键
                byte[] rowBytes = CellUtil.cloneRow(c);
                //获取列族
                byte[] familyBytes = CellUtil.cloneFamily(c);
                //获取列族下的列名称
                byte[] qualifierBytes = CellUtil.cloneQualifier(c);
                //列字段的值
                byte[] valueBytes = CellUtil.cloneValue(c);

                System.out.print(new String(rowBytes)+" ");
                System.out.print(new String(familyBytes)+":");
                System.out.print(new String(qualifierBytes)+" ");
                System.out.println(new String(valueBytes));
            }
            System.out.println("-----------------------");
        }
        }

9.3.2 行过滤器
  • RowFilter
  public void testFilter2() throws Exception {

// 行过滤器  需要一个比较运算符和比较器
RowFilter rf1 = new RowFilter(CompareFilter.CompareOp.LESS, new        BinaryComparator(Bytes.toBytes("user002")));
		 testScan(rf1);

		 RowFilter rf2 = new RowFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("01"));//rowkey包含"01"子串的
		 testScan(rf2);
}   
9.3.3 列族的过滤器
  • FamilyFilter
  public void testFilter3() throws Exception {

//针对列族名的过滤器   返回结果中只会包含满足条件的列族中的数据
		FamilyFilter ff1 = new FamilyFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("base_info")));
	    FamilyFilter ff2 = new FamilyFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("base")));
		testScan(ff2);

}   
9.3.4 列名的过滤器
  • QualifierFilter
public void testFilter4() throws Exception {

//针对列名的过滤器 返回结果中只会包含满足条件的列的数据
	QualifierFilter qf1 = new QualifierFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("password")));
	QualifierFilter qf2 = new QualifierFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("user")));
	testScan(qf2);
}
9.3.5 列值的过滤器
  • SingleColumnValueFilter
public void testFilter4() throws Exception {
    
//针对指定一个列的value的比较器来过滤
		ByteArrayComparable comparator1 = new RegexStringComparator("^zhang"); //以zhang开头的
		ByteArrayComparable comparator2 = new SubstringComparator("si");       //包含"si"子串
		SingleColumnValueFilter scvf = new SingleColumnValueFilter("base_info".getBytes(), "username".getBytes(), CompareFilter.CompareOp.EQUAL, comparator2);
		testScan(scvf);

}
9.3.6 多个过滤器同时使用
public void testFilter4() throws Exception {
    
//多个过滤器同时使用   select * from t1 where id >10 and age <30
    
//构建一个列族的过滤器            
FamilyFilter cfff1 = new FamilyFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("base")));

//构建一个列的前缀过滤器
            ColumnPrefixFilter cfff2 = new ColumnPrefixFilter("password".getBytes());

//指定多个过滤器是否同时都要满足条件
            FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);

            filterList.addFilter(cfff1);
            filterList.addFilter(cfff2);
            testScan(filterList);
}    

你可能感兴趣的:(大数据技术体系,java,hbase,数据库)