先简单讲讲只用HBase来实现分页的思路:
HBase利用scan来扫描表,通过startKey,stopKey来确定扫描范围,在需要进行分页时可以结合HBase提供的PagefFilter过滤扫描的行数使scan返回N条数据达到分页的目的(N为每页的记数),此时有以下两种方案达可以达到分页目的:
 
1. 在得到scan结果后把上一页的最后一条数据作为scan下一页时的startKey,但是此时下一页的数据在传到客户端时就要排除第一条数据了(因为第一条的数据是上一页的)
 
2.在每次scan时多查询一条数据(即返回N+1)作为下一页的startKey
 
以上的方案存有个大前提:HBase的RowKey必须是序列增长(类似1,2,3,....)的,否则的话虽然能定位到下一页的startkey,但是当我要查询上一页/上N页时就不能够定位到此时的startkey了。
 
所以解决这个大前提的方案就是添加一个序列ID到RowKey中来帮助起始键定位到对应偏移量的位置,但是当你的RowKey存在其他字符(如汉字)时就不能简单的将序列ID添加到RowKey了。(所以仅仅通过HBase来实现分页还是比较麻烦的,特别是RowKey比较复杂的时候)
 
下面是具体的实现方案:
 
项目场景:按条件查询并实现分页(如按澳门,三亚,2016-01-02查询并分页)
 
这里我选择使用Phoenix来操作HBase,原因是对于简单条件的查询Phoenix速度快,并且Phoenix提供了生成序列ID的方法,对于熟悉SQL语句的开发者来说可以很好的提高开发效率。
 
步骤:(HBase中存在TRAVEL表)
 
1.在Phoenix中为TRAVEL表创建视图TRAVEL
CREATE VIEW TRAVEL (ROWKEY VARCHAR PRIMARY KEY,INFO.SP VARCHAR,INFO.EP VARCHAR,INFO.ST VARCHAR,INFO.ET VARCHAR);
 (INFO为HBase表TRAVEL的列族名)
视图TRAVEL中的一段数据如下:
 
2.建立sequence(序列)
CREATE SEQUENCE SEQ;
 
3.在Phoenix中新建表PAGETRAVEL
CREATE TABLE TRAVEL (ROWKEY VARCHAR PRIMARY KEY,INFO.SP VARCHAR,INFO.EP VARCHAR,INFO.ST VARCHAR,INFO.ET VARCHAR,PAGEID BIGINT);
(字段PAGEID就是帮助起始健定位对应偏移量的分页ID)
4.通过Phoenix的UPSERT SELECT将视图TRAVEL中的数据全部插入到PAGETRAVEL表中
UPSERT INTO PAGETRAVEL SELECT ROWKEY,SP,EP,ST,ET,NEXT VALUE FOR SEQ FROM TRAVEL;
PAGETRAVEL表中的部分数据如下:    
有了PAGEID后就可以轻易的确定每页起始键对应的偏移量。
 
5.得到每页起始键的偏移量(PAGEID)
SELECT PAGEID FROM TRAVEL WHERE ROWKEY LIKE '澳门三亚%' AND ST >= '2016-01-02';
 
6.分页查询
SELECT * FROM TRVELS WHERE PAGEID > PAGEID*(PAGENUM-1)*N ORDER BY PAGEID LIMIT N WHERE ROWKEY LIKE '澳门三亚%';

(PAGENUM为当前页数)

关键代码实现:

public List findPageRecords(int currentPageNum, int pageSize,String ST,String SP,String EP) {
//得到每页起始键的偏移量,第一个参数为SQL语句,第二个参数为返回值类型的Class对象,第三个参数为占位符值(为可变参数)
int startkey = jdbcTemplate.queryForObject("SELECT * FROM TRAVELS WHERE ST >= ? AND ROWKEY LIKE ? LIMIT 1",Integer.class,ST,SP+EP+"%"); //第一个参数为SQL语句,第二参数的RowMapper将每一行结果映射成一个Java对象,方便将其他封装到JavaBean中,第三个参数为占位符值(为可变参数)
List<Travel> travels = jdbcTemplate.query("SELECT * FROM TRAVELS where PAGEID >= ? AND ST >= ? AND ROWKEY LIKE ? limit 8",
new RowMapper<Travel>() {
public Travel mapRow(ResultSet rs, int rowNum)
throws SQLException {
Travel travel = new Travel();
travel.setROWKEY(rs.getString("ROWKEY"));
travel.setURL(rs.getString("URL"));
travel.setSP(rs.getString("SP"));
travel.setEP(rs.getString("EP"));
travel.setST(rs.getString("ST"));
travel.setET(rs.getString("ET"));
travel.setSIGHTS(rs.getString("SIGHTS"));
travel.setALLDATE(rs.getString("ALLDATE"));
travel.setHOTEL(rs.getString("HOTEL"));
travel.setTOTALPRICE(rs.getString("TOTALPRICE"));
travel.setTRAFFIC(rs.getString("TRAFFIC"));
travel.setTRAVELTYPE(rs.getString("TRAVELTYPE"));
travel.setSUPPLIER(rs.getString("SUPPLIER"));
return travel;
}
},startkey+(currentPageNum - 1)*pageSize,ST,SP+EP+"%");
return travels;
}

总结:通过与Spring JDBC的集成,利用Phoneix可以很轻易的实现HBase分页极大地提高开发效率,并且Phoenix还提供了二级索引的功能。

 

SHDP--Working with HBase(三)之HBase+Phoenix实现分页的更多相关文章

  1. HBase之八--(2):HBase二级索引之Phoenix

    1. 介绍 Phoenix 是 Salesforce.com 开源的一个 Java 中间件,可以让开发者在Apache HBase 上执行 SQL 查询.Phoenix完全使用Java编写,代码位于 ...

  2. HBase(三)HBase架构与工作原理

    一.系统架构 注意:应该是每一个 RegionServer 就只有一个 HLog,而不是一个 Region 有一个 HLog. 从HBase的架构图上可以看出,HBase中的组件包括Client.Zo ...

  3. HBase 系列(三)HBase Shell

    HBase 系列(三)HBase Shell ./hbase shell # 进入 hbase 命令行 (1) HBase 命令帮助 help # 查看 HBase 所有的命令 create # 或 ...

  4. HBase 学习之路(三)—— HBase基本环境搭建

    一.安装前置条件说明 1.1 JDK版本说明 HBase 需要依赖JDK环境,同时HBase 2.0+ 以上版本不再支持JDK 1.7 ,需要安装JDK 1.8+ .JDK 安装方式见本仓库: Lin ...

  5. HBase 系列(三)—— HBase 基本环境搭建

    一.安装前置条件说明 1.1 JDK版本说明 HBase 需要依赖 JDK 环境,同时 HBase 2.0+ 以上版本不再支持 JDK 1.7 ,需要安装 JDK 1.8+ .JDK 安装方式见本仓库 ...

  6. HBase单机安装及Phoenix JDBC连接

    HBase是建立在Hadoop文件系统之上的分布式面向列的数据库,它是横向扩展的.它利用了Hadoop的文件系统(HDFS)提供的容错能力. HBase提供对数据的随机实时读/写访问,可以直接HBas ...

  7. 读者来信 | 刚搭完HBase集群,Phoenix一启动,HBase就全崩了,是什么原因?(已解决)

    前言:之前有朋友加好友与我探讨一些问题,我觉得这些问题倒挺有价值的:于是就想在本公众号开设一个问答专栏,方便技术交流与分享,专栏名就定为:<读者来信>.如遇到本人能力有限难以解决的问题,我 ...

  8. 「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践

    Phoenix是构建在HBase上的一个SQL层,能让我们用标准的JDBC APIs对HBase数据进行增删改查,构建二级索引.当然,开源产品嘛,自然需要注意“避坑”啦,阿丸会把使用方式和最佳实践都告 ...

  9. HBase(三): Azure HDInsigt HBase表数据导入本地HBase

    目录: hdfs 命令操作本地 hbase Azure HDInsight HBase表数据导入本地 hbase hdfs命令操作本地hbase: 参见  HDP2.4安装(五):集群及组件安装 , ...

随机推荐

  1. 《TCP/IP具体解释卷2:实现》笔记--4种不同类型的mbuf

    mbuf的主要用途是保存子进程和网络接口间互相传递的用户数据.但mbuf也用于保存其它各种数据:源于目的地址.插口 选项等等. 以下介绍我们要遇到的四种类型的mbuf,它们根据在成员m_flag中填写 ...

  2. 0..n去掉一个数,给你剩下的数,找出去掉的那个数

    转载请注明转自blog.csdn.net/souldak , 微博@evagle 首先,考虑没有去掉那些数,如果n是奇数,n+1个最低位肯定是0101...01,count(0)=count(1),如 ...

  3. IOS基于新浪微博开放平台微博APP

    1.基于新浪微博开放平台APP源码 2.gitHub源代码下载地址 https://github.com/whzhaochao/SinaWeiBoOpen 3.用到的第三放开源库 3.1  RTLab ...

  4. html_day4+css

    表单控件共有的属性: enabled:表示表单控件可用 disabled:表示表单控件被禁用 readonly:表示表单控件只能读name属性值的作用: 需要将表单的数据提交到服务器处理就要写name ...

  5. .net DataTable 正确排序姿势

    关于dataTable中根据列排序正确姿势做个随笔,方便查阅 System.Data.DataTable dt = new System.Data.DataTable(); dt.Columns.Ad ...

  6. FULL JOIN 与 CROSS JOIN

    FULL JOIN 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行.(返回JOIN 两端表的所有数据,无论其与另一张表有没有匹配.显示左连接.右连接和内连接的并集) FULL JOIN ...

  7. 原创+部分引用啦:C# Winform界面中的分隔线问题

    C sharp 中Winform中的控件很多,一个小小的问题居然会绕上一个小弯子,做界面的时候, 你需要在界面上弄一条分隔线,把相关的功能分隔开来,结果原来在其它 IDE编辑器里很容易实现的这个功能, ...

  8. (原)ubuntu14手动安装matplotlib1.5

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5681059.html 参考网址: http://matplotlib.org/users/instal ...

  9. Java中的IO学习总结

    今天刚刚看完java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬盘.内存.键盘等处理 ...

  10. 2015.4.2-SQL 简单语句(一)

    1.创建一个student表 create table student_masen( sno char(4) not null primarykey sname nchar(10) not null ...