HBase基本操作 (2)

批量删除需要借助Delete对象。

查询 单条结果查询 Result result = hBaseDao.queryByTableNameAndRowKey("LBS", 9223372036854775803L); System.out.println(result.isEmpty()); result.listCells().forEach(cell -> { System.out.println( " row:" + Bytes.toLong(CellUtil.cloneRow(cell)) + " family:"+ Bytes.toString(CellUtil.cloneFamily(cell)) + " qualifier: " + Bytes.toString(CellUtil.cloneQualifier(cell)) + " value:" + Bytes.toString(CellUtil.cloneValue(cell))); });

queryByTableNameAndRowKey()该方法是通过表名和rowKey查询数据,这里的rowKey支持多种类型,Long,double,Integer几种类型。
至于这里传什么类型的参数,取决于插入数据时rowKey的类型,虽然HBase里存储的都是字节数组,但是对类型是敏感的,如果类型对不上可能会出错。

批量扫描 // 构建scan Scan scan = new Scan(); // 设置时间戳,计算时间差 Long timeDifference = 2L * 30L * 24L * 60L * 60L * 1000L; Long endTime = System.currentTimeMillis(); Long fromTime = endTime - timeDifference; // 设置时间过滤器 FilterList filterList = new FilterList(); Filter startTimeFilter = new SingleColumnValueFilter( DEFAULT_COLUMN_FAMILY.getBytes(), DATA_CREATE_TIME.getBytes(), CompareFilter.CompareOp.GREATER, Bytes.toBytes(fromTime) ); Filter endTimeFilter = new SingleColumnValueFilter( DEFAULT_COLUMN_FAMILY.getBytes(), DATA_CREATE_TIME.getBytes(), CompareFilter.CompareOp.LESS, Bytes.toBytes(endTime) ); filterList.addFilter(startTimeFilter); filterList.addFilter(endTimeFilter); scan.setFilter(filterList); // 获取结果集 ResultScanner resultScanner = hBaseTemplate.queryByScan(TABLE_NAME, scan); // 遍历结果集 try{ if (resultScanner != null) { resultScanner.forEach(result -> { List<Cell> cellList = result.listCells(); ... } } }finally{ if (resultScanner != null) { resultScanner.close(); } }

批量查询可以通过queryByScan()方法实现,第一个参数是表名,第二个参数是scan,通过构建不同的scan来查询,过滤器也是在构建scan对象是添加的,可以添加多个过滤器。

需要注意的是这里的ResultScanner类,在遍历结果集时需要使用try-finally结构,在使用完resultScanner对象之后关闭该对象。HBase官方文档上强调了这一点。因此在使用ResultScanner对象时需要格外注意。

常见过滤器:

行健过滤器:RowFilter

列族过滤器:FamilyFilter

值过滤器:ValueFilter

列过滤器:QualifierFilter

单列值过滤器:SingleColumnValueFilter(会返回满足条件的行)

单列值排除过滤器:SingleColumnExcludeFilter(返回排除了该列的结果,与单列值过滤器相反)

前缀过滤器:PrefixFilter(这个过滤器是针对行健的,在构造方法中传入字节数组形式的内容,过滤器会去匹配行健)

页数过滤器:PageFilter(使用pageFilter过滤器的时候需要注意,并不是设置了页数大小就能返回相应数目的结果)

String tableName = "RECOMMEND_ENGINE_DATA_MODEL"; Scan scan = new Scan(); PageFilter pageFilter = new PageFilter(1); scan.setFilter(pageFilter); ResultScanner resultScanner = hBaseDao.queryByScan(tableName, scan); try{ resultScanner.forEach(result -> { result.listCells().forEach(cell -> { // process }); }finally{ if (resultScanner != null) { resultScanner.close(); } }

上面这段代码中设置了页面大小为1,预期是返回一条数据,但是结果会返回两条数据,这时返回的结果数会取决于regionServer的数量。

如果是FilterList,FilterList的顺序会影响PageFilter的效果。

一般比较型过滤器,需要用CompareFilter.CompareOp中的比较运算符。所有的过滤器都是用Scan对象去设置。

多过滤器查询 String tableName = "HBase-component"; Scan scan = new Scan(); PageFilter pageFilter = new PageFilter(1); SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter( "CF1".getBytes(), "col1".getBytes(), CompareFilter.CompareOp.EQUAL, new SubstringComparator("group")); singleColumnValueFilter.setFilterIfMissing(true); FilterList filterList = new FilterList(); filterList.addFilter(singleColumnValueFilter); filterList.addFilter(pageFilter); scan.setFilter(filterList); ResultScanner resultScanner = hBaseDao.queryByScan(tableName, scan); try { resultScanner.forEach(result -> { result.listCells().forEach(cell -> { System.out.println( " row:" + Bytes.toString(CellUtil.cloneRow(cell)) + " family:"+ Bytes.toString(CellUtil.cloneFamily(cell)) + " qualifier: " + Bytes.toString(CellUtil.cloneQualifier(cell))+ " value:" + Bytes.toString(CellUtil.cloneValue(cell))); }); }); } finally { if (resultScanner != null) { resultScanner.close(); } }

多过滤器需要用到FilterList,也是直接设置到Scan对象中。多过滤器的时候需要注意过滤器的顺序问题,例如上面代码中如果将两个过滤器调换顺序,查询的结果也是不一样的。

结果集的映射

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyyjff.html