habase 分页功能的详细解说及源码

由于最近刚接触 hadoop 这么高端的东西,一开始搞的我也有点头晕,研究了一段时间,现在脑子稍微清醒点了,把自己实现的功能来跟大家分享一下吧

 

先说一下用到的技术吧

1、struts2

2、hbase(集群环境就不说了)

3、easyui(前台展示)

 

实现功能

hbase分页功能,并在jsp页面显示

 

大家应该都知道,hbase的主要功能不是干这活的,这样基本上就又回到关系型数据库了,就当是 自己没事干瞎玩研究一下吧,我现在在写供别人调用的接口,光在控制台输出也

没啥意思,所有就想在jsp页面显示一下,于是就搞了一下,显示很好弄,我在hbase里面弄了一万条数据,第一次直接把浏览器 干崩溃了,然后想得弄个分页,从网上搜了下都

说hbase没有分页功能,后来在度娘的帮助下找到了一篇关于hbase分页实现的文章,最棒的是还有源码哈哈,拿过来不能直接用,自己有根据现有的环境大修了一下,最终终于

把这骨头搞定了。

 

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
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.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
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.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.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.util.Bytes;
import org.json.JSONArray;


import test.creattable.TBData;


import com.core.action.BaseAction;
import com.core.bean.DataGridJson;
import com.google.gson.JsonArray;


public class Users extends BaseAction<Model> {
private static Configuration config = null;
private static HTablePool tp = null;
static {
// 加载集群配置
config = HBaseConfiguration.create();
config.set("hbase.master", "10.158.7.190:60000");
config.set("hbase.zookeeper.quorum", "10.158.7.190");
config.set("hbase.zookeeper.property.clientPort", "2181");


// 创建表池(可伟略提高查询性能,具体说明请百度或官方API)
tp = new HTablePool(config, 10);
}
private String rowkey;// 开始


public Users() {
super(Model.class);
}


public String execute() {
return SUCCESS;
}


public String getAllData() throws IOException {// 查询所有数据
PrintWriter out = getResponse().getWriter();
dgdata = new DataGridJson();//基于easyui分页功能的公用类

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

// page(第几页)、rows(每页多少行)这两个参数是页面传给后台的
System.out.println("rows:" + rows + " " + "page:" + page);


// 获取最大返回结果数量
if (rows == null || rows == 0L) {
rows = 20;
}
if (page == null || page == 0L) {
page = 1;
}
// 计算起始页和结束页
Integer firstPage = (page - 1) * rows;
System.out.println("fiestPage:" + firstPage);


Integer endPage = firstPage + rows;
System.out.println("endPage:" + endPage);
// 从表池中取出HBASE表对象
HTableInterface table = getTable("users");
// 获取筛选对象

Scan scan = getScan();
// 给筛选对象放入过滤器(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取出
List list1 = new ArrayList();
if (rowkey == null || rowkey.equals("")) {
for (Result result : scanner) {
String row = toStr(result.getRow());


if (i >= firstPage && i < endPage) {
// System.out.println("row; " + row);
for (KeyValue kv : result.raw()){

//Model 是我自己创建的,由于struts2基础类操作比较方便,于是我就把 hbase 里面的rowkey 、列族、列名和列值 创建了一个Model,代码在下面 
Model m = new Model();
m.setRowkey(new String(kv.getRow()));// 主键rowkey
m.setInfo(Bytes.toString(kv.getFamily()));// 列族
m.setLieming(new String(kv.getQualifier()));// 列名
m.setLiezhi(Bytes.toString(kv.getValue()));// 列值
System.out.println("lieming:" + new String(kv.getRow()));
list1.add(m);
}
rowList.add(getBytes(row));
}
i++;
// System.out.println("i:"+rowList.size());
}
} else {//单点值查询
Get g = new Get(Bytes.toBytes(rowkey));
// HTableInterface t = getTable("users");
Result r = table.get(g);
// System.out.println(r.size());


if (r.size() <= 0) {
System.out.println("点名称不存在");
out.print("0");
} else {
for (KeyValue kv : r.raw()) {
Model m = new Model();
m.setRowkey(new String(kv.getRow()));// 主键rowkey
m.setInfo(Bytes.toString(kv.getFamily()));// 列族
m.setLieming(new String(kv.getQualifier()));// 列名
m.setLiezhi(Bytes.toString(kv.getValue()));// 列值
// System.out.println("lieming:" + new
// String(kv.getRow()));
list1.add(m);
i++;
}
}
}

//下面的这两句是我基于easyui 的分页功能 生成的一个返回json的公用类,封装了一些分页必须使用d
// long total = i;//总记录数
dgdata.setRows(list1);// 每页的行数
dgdata.setTotal(i);// 用来显示总的记录数


return SUCCESS;
}


public String checkRowkey() throws IOException {
PrintWriter out=getResponse().getWriter();
Get g = new Get(Bytes.toBytes(rowkey));
// HTableInterface t = getTable("users");
HTableInterface table = getTable("users");
Result r = table.get(g);
// System.out.println(r.size());
if (r.size() <= 0) {
//System.out.println("点名称不存在");
out.print(false);
}else{
out.print(true);
}
return null;


}


/*
* 获取hbase的表
*/
public static HTableInterface getTable(String tableName) {


if (StringUtils.isEmpty(tableName))
return null;


return tp.getTable(getBytes(tableName));
}


/* 转换byte数组 */
public static byte[] getBytes(String str) {
if (str == null)
str = "";


return Bytes.toBytes(str);
}


/**
* 查询数据

* @param tableKey
*            表标识
* @param queryKey
*            查询标识
* @param startRow
*            开始行
* @param paramsMap
*            参数集合
* @return 结果集
*/
public static TBData getDataMap(String tableName, 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 = 20;


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


// 计算起始页和结束页
Integer firstPage = (currentPage - 1) * pageSize;
System.out.println("fiestPage:" + firstPage);


Integer endPage = firstPage + pageSize;
System.out.println("endPage:" + endPage);
// 从表池中取出HBASE表对象
HTableInterface table = getTable(tableName);
// 获取筛选对象
// Scan scan = getScan(startRow, stopRow);
Scan scan = getScan();
// 给筛选对象放入过滤器(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取出
List list1 = new ArrayList();
for (Result result : scanner) {
String row = toStr(result.getRow());
if (i >= firstPage && i < endPage) {
System.out.println("row; " + row);
for (KeyValue kv : result.raw()) {
Model m = new Model();
m.setRowkey(new String(kv.getRow()));// 主键rowkey
m.setInfo(Bytes.toString(kv.getFamily()));// 列族
m.setLieming(new String(kv.getQualifier()));// 列名
m.setLiezhi(Bytes.toString(kv.getValue()));// 列值
System.out
.println("lieming:" + new String(kv.getRow()));
list1.add(m);
}
rowList.add(getBytes(row));
}
i++;


}
System.out.println(rowList.size());


JSONArray array1 = new JSONArray(list1);
// .out.println("array:"+array.toString());
System.out.println("array1:" + array1.toString());


} catch (IOException e) {
e.printStackTrace();
} finally {
closeScanner(scanner);
}


return tbData;
}


private static int getTotalPage(int rows, int totalCount) {
int n = totalCount / rows;
if (totalCount % rows == 0){
return n;
} else {
return ((int) n) + 1;
}
}


// 获取扫描器对象
// private static Scan getScan(String startRow, String stopRow) {
// Scan scan = new Scan();
// scan.setStartRow(getBytes(startRow));
// scan.setStopRow(getBytes(stopRow));
//
// return scan;
// }
private static Scan getScan() {
Scan scan = new Scan();
// scan.setStartRow(getBytes(startRow));
// scan.setStopRow(getBytes(stopRow));
return scan;
}


/**
* 封装查询条件
*/
private static 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("demo1"), getBytes("info"),
// CompareOp.EQUAL, getBytes("shuju"));
// filter2 = newFilter(getBytes("demo99"), getBytes("info"),
// CompareOp.LESS, getBytes("shuju"));
// filterList.addFilter(filter1);
// filterList.addFilter(filter2);
if (isPage) {
filterList.addFilter(new FirstKeyOnlyFilter());
}
return filterList;
}


private static Filter newFilter(byte[] f, byte[] c, CompareOp op, byte[] v) {
return new SingleColumnValueFilter(f, c, op, v);
}


private static void closeScanner(ResultScanner scanner) {
if (scanner != null)
scanner.close();
}


/**
* 封装每行数据
*/
private static 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));
// System.out.println("eee:"+toStr(key)+" ddd:"+toStr(value));
}
return map;
}


/* 根据ROW KEY集合获取GET对象集合 */
private static List<Get> getList(List<byte[]> rowList){
List<Get> list = new LinkedList<Get>();
for (byte[] row : rowList) {
Get get = new Get(row);


get.addColumn(getBytes("info"), getBytes("shuju"));
// get.addColumn(getBytes("family1"), getBytes("column2"));
// get.addColumn(getBytes("family2"), getBytes("column1"));
list.add(get);
}
return list;
}


/**
* 封装配置的所有字段列族
*/
private static Map<byte[], byte[]> packFamilyMap(Result result) {
Map<byte[], byte[]> dataMap = null;
dataMap = new LinkedHashMap<byte[], byte[]>();
dataMap.putAll(result.getFamilyMap(getBytes("info")));
// dataMap.putAll(result.getFamilyMap(getBytes("shuju")));
return dataMap;
}


private static String toStr(byte[] bt) {
return Bytes.toString(bt);
}


public String getAllData1() throws IOException {// 查询所有数据
System.out.println("来过");
dgdata = new DataGridJson();
String tablename = "users";
HTable t = new HTable(HBaseConfiguration.create(), tablename);
List list = new ArrayList();
if (rowkey == null || this.getRowkey().equals("")) {
Scan s = new Scan();
ResultScanner rs = t.getScanner(s);
// List<Model> list = new ArrayList<Model>();


System.out.println(page + " " + rows);


for (Result r : rs) {
for (KeyValue kv : r.raw()) {
// for (int i = (page - 1) * rows; i < rows * page; i++) {
Model m = new Model();
m.setRowkey(new String(kv.getRow()));// 主键rowkey
m.setInfo(Bytes.toString(kv.getFamily()));// 列族
m.setLieming(new String(kv.getQualifier()));// 列名
m.setLiezhi(Bytes.toString(kv.getValue()));// 列值
System.out.println("lieming:" + new String(kv.getRow()));
list.add(m);
}
// }
}


} else {
Get g = new Get(Bytes.toBytes(rowkey));
Result r = t.get(g);
for (KeyValue kv : r.raw()) {
Model m = new Model();
m.setRowkey(new String(kv.getRow()));// 主键rowkey
m.setInfo(Bytes.toString(kv.getFamily()));// 列族
m.setLieming(new String(kv.getQualifier()));// 列名
m.setLiezhi(Bytes.toString(kv.getValue()));// 列值
System.out.println("lieming:" + new String(kv.getRow()));
list.add(m);
}
}
long total = list.size();


dgdata.setRows(list);
dgdata.setTotal(total);
return SUCCESS;
}


public String getRowkey() {
return rowkey;
}


public void setRowkey(String rowkey) {
this.rowkey = rowkey;
}


}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值