hbase分页查询实现

Hbase本身是没有分页查询的,我在网上找了很多资料来实现一个分页功能,在这里做了一下记录,分享给大家,有什么不足之处,请尽管指出。废话不多说,看代码。

import java.io.IOException;

import java.util.LinkedHashMap;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import org.apache.commons.lang.StringUtils;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.hbase.HBaseConfiguration;

import org.apache.hadoop.hbase.client.Get;

import org.apache.hadoop.hbase.client.HTableInterface;

import org.apache.hadoop.hbase.client.HTablePool;

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.filter.CompareFilter.CompareOp;

import org.apache.hadoop.hbase.filter.Filter;

import org.apache.hadoop.hbase.filter.FilterList;

import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;

import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;

import org.apache.hadoop.hbase.util.Bytes;

publicclass HBaseUtils {

privatestatic Configuration config = null;

privatestatic HTablePool tp = null;

static {

// 加载集群配置

config = HBaseConfiguration.create();

config.set("hbase.zookeeper.quorum", "xx.xx.xx");

config.set("hbase.zookeeper.property.clientPort", "2181");

// 创建表池(可伟略提高查询性能,具体说明请百度或官方API)

tp = new HTablePool(config, 10);

}

/*

* 获取hbase的表

*/

publicstatic HTableInterface getTable(StringtableName) {

if (StringUtils.isEmpty(tableName))

returnnull;

returntp.getTable(getBytes(tableName));

}

/* 转换byte数组 */

publicstaticbyte[] getBytes(String str) {

if (str == null)

str= "";

return Bytes.toBytes(str);

}

/**

* 查询数据

* @param tableKey 表标识

* @param queryKey 查询标识

* @param startRow 开始行

* @param paramsMap 参数集合

* @return结果集

*/

publicstatic TBData getDataMap(StringtableName, String startRow,

StringstopRow, Integer currentPage, Integer pageSize)

throws IOException {

List<Map<String, String>>mapList = null;

mapList = new LinkedList<Map<String,String>>();

ResultScanner scanner = null;

// 为分页创建的封装类对象,下面有给出具体属性

TBData tbData = null;

try {

// 获取最大返回结果数量

if (pageSize == null || pageSize == 0L)

pageSize = 100;

if (currentPage == null || currentPage == 0)

currentPage = 1;

// 计算起始页和结束页

IntegerfirstPage = (currentPage - 1) * pageSize;

IntegerendPage = firstPage + pageSize;

// 从表池中取出HBASE表对象

HTableInterfacetable = getTable(tableName);

// 获取筛选对象

Scanscan = getScan(startRow, stopRow);

// 给筛选对象放入过滤器(true标识分页,具体方法在下面)

scan.setFilter(packageFilters(true));

// 缓存1000条数据

scan.setCaching(1000);

scan.setCacheBlocks(false);

scanner= table.getScanner(scan);

int i = 0;

List<byte[]> rowList = new LinkedList<byte[]>();

// 遍历扫描器对象, 并将需要查询出来的数据row key取出

for (Result result : scanner) {

String row = toStr(result.getRow());

if (i >= firstPage && i< endPage) {

rowList.add(getBytes(row));

}

i++;

}

// 获取取出的row key的GET对象

List<Get>getList = getList(rowList);

Result[]results = table.get(getList);

// 遍历结果

for (Result result : results) {

Map<byte[], byte[]> fmap = packFamilyMap(result);

Map<String, String> rmap = packRowMap(fmap);

mapList.add(rmap);

}

// 封装分页对象

tbData= new TBData();

tbData.setCurrentPage(currentPage);

tbData.setPageSize(pageSize);

tbData.setTotalCount(i);

tbData.setTotalPage(getTotalPage(pageSize, i));

tbData.setResultList(mapList);

} catch (IOException e) {

e.printStackTrace();

} finally {

closeScanner(scanner);

}

return tbData;

}

privatestaticint getTotalPage(int pageSize, int totalCount) {

int n = totalCount / pageSize;

if (totalCount % pageSize == 0) {

return n;

} else {

return ((int) n) + 1;

}

}

// 获取扫描器对象

privatestatic Scan getScan(String startRow,String stopRow) {

Scan scan = new Scan();

scan.setStartRow(getBytes(startRow));

scan.setStopRow(getBytes(stopRow));

return scan;

}

/**

* 封装查询条件

*/

privatestatic FilterList packageFilters(boolean isPage) {

FilterList filterList = null;

// MUST_PASS_ALL(条件 AND) MUST_PASS_ONE(条件OR)

filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);

Filter filter1 = null;

Filter filter2 = null;

filter1 = newFilter(getBytes("family1"), getBytes("column1"),

CompareOp.EQUAL, getBytes("condition1"));

filter2 = newFilter(getBytes("family2"), getBytes("column1"),

CompareOp.LESS, getBytes("condition2"));

filterList.addFilter(filter1);

filterList.addFilter(filter2);

if (isPage) {

filterList.addFilter(new FirstKeyOnlyFilter());

}

return filterList;

}

privatestatic Filter newFilter(byte[] f, byte[] c, CompareOp op, byte[] v) {

returnnew SingleColumnValueFilter(f, c, op,v);

}

privatestaticvoid closeScanner(ResultScannerscanner) {

if (scanner != null)

scanner.close();

}

/**

* 封装每行数据

*/

privatestatic Map<String, String>packRowMap(Map<byte[], byte[]> dataMap) {

Map<String, String> map = new LinkedHashMap<String, String>();

for (byte[] key : dataMap.keySet()) {

byte[] value = dataMap.get(key);

map.put(toStr(key), toStr(value));

}

return map;

}

/* 根据ROW KEY集合获取GET对象集合 */

privatestatic List<Get> getList(List<byte[]> rowList) {

List<Get> list = new LinkedList<Get>();

for (byte[] row : rowList) {

Getget = new Get(row);

get.addColumn(getBytes("family1"), getBytes("column1"));

get.addColumn(getBytes("family1"), getBytes("column2"));

get.addColumn(getBytes("family2"), getBytes("column1"));

list.add(get);

}

return list;

}

/**

* 封装配置的所有字段列族

*/

privatestatic Map<byte[], byte[]> packFamilyMap(Result result){

Map<byte[], byte[]> dataMap = null;

dataMap = new LinkedHashMap<byte[], byte[]>();

dataMap.putAll(result.getFamilyMap(getBytes("family1")));

dataMap.putAll(result.getFamilyMap(getBytes("family2")));

return dataMap;

}

privatestatic String toStr(byte[] bt) {

return Bytes.toString(bt);

}

publicstaticvoid main(String[] args) throws IOException {

// 拿出row key的起始行和结束行

// #<0<9<:

String startRow = "aaaa#";

String stopRow = "aaaa:";

int currentPage = 1;

int pageSize = 20;

// 执行hbase查询

getDataMap("table", startRow, stopRow, currentPage,pageSize);

}

}

class TBData {

private Integer currentPage;

private Integer pageSize;

private Integer totalCount;

private Integer totalPage;

private List<Map<String, String>> resultList;

public Integer getCurrentPage() {

returncurrentPage;

}

publicvoid setCurrentPage(IntegercurrentPage) {

this.currentPage = currentPage;

}

public Integer getPageSize() {

returnpageSize;

}

publicvoid setPageSize(Integer pageSize) {

this.pageSize = pageSize;

}

public Integer getTotalCount() {

returntotalCount;

}

publicvoid setTotalCount(Integer totalCount){

this.totalCount = totalCount;

}

public Integer getTotalPage() {

returntotalPage;

}

publicvoid setTotalPage(Integer totalPage) {

this.totalPage = totalPage;

}

public List<Map<String, String>> getResultList() {

returnresultList;

}

publicvoidsetResultList(List<Map<String, String>> resultList) {

this.resultList = resultList;

}

}

时间: 2024-10-05 05:42:09

hbase分页查询实现的相关文章

HBase多条件及分页查询的一些方法

HBase是Apache Hadoop生态系统中的重要一员,它的海量数据存储能力,超高的数据读写性能,以及优秀的可扩展性使之成为最受欢迎的NoSQL数据库之一.它超强的插入和读取性能与它的数据组织方式有着密切的关系,在逻辑上,HBase的表数据按RowKey进行字典排序, RowKey实际上是数据表的一级索引(Primary Index),由于HBase本身没有二级索引(Secondary Index)机制,基于索引检索数据只能单纯地依靠RowKey.也只有使用RowKey查询数据才能得到非常高

Java链接HBASE数据库,创建一个表,删除一张表,修改表,输出插入,修改,数据删除,数据获取,显示表信息,过滤查询,分页查询,地理hash

准备工作 1.创建Java的Maven项目 创建好的目录结构如下:  另外注意junit的版本,最好不要太高,最开始笔者使用的junit4.12的,发现运行的时候会报错.最后把Junit的版本改成4.7的之后,问题解决了. 创建测试工具类HbaseDemo,为了保证能够让Hbase运行,需要最开始写出如下配置: package toto.com.hbase; import java.util.ArrayList; import java.util.Iterator; import org.apa

hbase实现分页查询

[Author]: kwu hbase实现分页查询,实现按时间查询最新的15条,hbase的查询主要是通过rowkey来进行的,保证查询的高效.column的filter查询效率较低. 1.rowkey的设计 以时间的倒序进行查询,如20150818_152130来看,设计rowkey 20150818的hash64值+(999999-152130). 1)MurmurHash的64的冲突非常小,并实现rowkey的散列. 2)日分秒与999999的差值,可以实现逆序 2.插入数据的操作 Str

mysql分库 分页查询

Mysql海量数据分表分库如何列表分页? 1.现在使用ElasticSearch了.基于Lucene的解决方案 2.必须将mysql里的数据写入到类似hbase这样的分布式数据库,查询快.但分页.查询的话,可以在hbase前加一层solr,用于建立数据索引 如何对分库后的数据进行分页查询? yeyingsheng 发布于 2015/04/21 10:18 阅读 7K+ 收藏 1 答案 7 Spring iBATIS si项目,现在连接6台mysql数据库,路由分库算法是根据id的hash值%6,

Hbase 分页设计

hbase 数据获取方式 直接根据 rowkey 查找,速度最快 scan,指定 startrowkey.endrowkey 和 limit获取数据,在 rowkey 设计良好的情况下,效率也不错 全表扫,强烈不推荐这种做法,效率极差,在线业务不用考虑这种方式 hbase 数据排序怎么做? 我觉得这个分两种情况,一是数据量比较少,业务上每次拉取所有的数据,可以在客户端做排序,二是数据比较多,需要分页,这种情况下客户端做显然不合适,因为要从服务器拉取所有数据,排序完成,获取某一页,剩余的数据全都不

Oracle分页查询

一.利用rownum,无order by(最优方案) 如下例查询出来5003行数据,然后扔掉了前面5000行,返回后面的300行.经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然. SELECT * FROM (SELECT ROWNUM AS rowno, t.* FROM XXX t WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd') AND TO_DATE ('20060731',

QBC查询、离线条件查询(DetachedCriteric)和分页查询模版

一.QBC检索步骤 QBC检索步骤: 1.调用Session的createCriteria()方法创建一个Criteria对象. 2.设定查询条件.Expression类提供了一系列用于设定查询条件的静态方法, 这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件. Criteria的add()方法用于加入查询条件. 3.调用Criteria的list()方法执行查询语句.该方法返回List类型的查询结果,在 List集合中存放了符合查询条件的持久化对象. 比较运

Linq高级查询与分页查询

Linq高级查询 以~开头: r=>r.Name.StartsWith("李"); 以~结尾: r=>r.Name.EndsWith("光"); 包含(模糊查询): r=>r.Name.Contains("四"); 数据总个数: Con.Goods.Count();||Con.Users.ToList().count; 最大值: Con.Goods.ToList().Max(r=>r.Price); 最小值: Con.Go

bos 第4 (区域excel批量导入、区域通用分页查询、分区的添加、分区多条件分页查询、分区导出excel)

BOS项目笔记 第4天 今天内容安排: 1.区域批量导入功能 jQuery OCUpload(一键上传插件).apache POI.pinyin4j 2.实现区域的分页查询 3.对分页代码重构 4.添加分区(combobox下拉框) 5.分区的组合条件分页查询 6.分区数据导出功能 1. 区域数据批量导入功能 1.1 一键上传插件使用 ajax不能做文件上传. 第一步:在jsp页面中引入插件的js文件 <script type="text/javascript" src=&quo