记录生活记录美_hbase使用过程中的记录

背景:公司想做大数据相关的应用,招了一位大数据方面的美女攻城狮,我作为打杂的被分配到了底下.

1)关于scan中的startrow和stoprow

关于分页遇到的问题

在java上刚开始看到这两个方法的时候(setStartrow,setStoprow)我还以为是和截取字符串substring差不多的用法.一个代表起始rowkey,一个代表结束rowkey.但是,实际上还就是这个意思.不同的是这个rowkey是按照字符来进行排序的(我在hbase中保存的就是1,2,3..之类的rowkey).结果悲催了,我分别赋值为1和10,结果给我返回为空,百思不得其解.后来多看了几篇文章才知道原来是通过字符来排序的.如图, scan 'blogtable' , {STARTROW => '1',STOPROW => '8'}   查询的数据是1,17,18(PS:以前我这里只有1,2,3三条数据,查询不到数据的时候我还以为是因为数据不够角标越界.....后来多加了几条数据才看出来)

 

好了,上面知道问题出在了哪里,但是目前对于分页还是一无所知,继续查资料看看去

 

关于分页的处理:

通过查了一些文章,找到了一个比较简单易懂的处理分页的方法.下面分享一下

 Table table = conn.getTable(TableName.valueOf(tableName));//这里的conn是 conn
// = ConnectionFactory.createConnection(conf); //conf是我们的配置信息,我这里对获取conn进行了封装
//分页相关主要代码在这里  
Filter pageFilter = new PageFilter(pageSize);//分页查询在这里
	            Filter rowFilter = new RowFilter(CompareFilter.CompareOp.GREATER,
	                    new BinaryComparator(Bytes.toBytes(lastRowKey)));//lastRowKey最 //后一个rowkey,上一次查询的,第一次查询的话这里可以为""
	            filterList.addFilter(pageFilter);//把pageFilter放进lists中
	            scan.setFilter(filterList);//添加进scan中
//后面的就是查询,以及对查询到的相关数据进行二次处理了
 ResultScanner rs = table.getScanner(scan);
	            Result result;
	            int rowNum = 0;
	            while ((result = rs.next()) != null) {
	                if (rowNum >= pageSize) {//pageSize是要显示的内容数
	                    break;
	                }
	                List<Cell> listCells = result.listCells();
	                Map<String,Object> map = new HashMap<String,Object>();
	                String row = "";
	                for (Cell cell : listCells) {
//下面是一些业务逻辑,不必在意
	                	 row =Bytes.toString( cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
	                    String value =Bytes.toString( cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
	                    String family =  Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength());
	                    String quali = Bytes.toString( cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength());
	                    if(quali != null && quali.length() != 0) { 
	                    	map.put(family+"_"+quali, value);
	                    }else{
	                    	map.put(family, value);
	                    }
	                    /* E e = getDataByRowKey(e,tableName, get);
	                    if (!StringUtils.isEmpty(generalNewsInfo.getRowkey())) {
	                        dataList.add(generalNewsInfo);
	                        rowNum++;
	                    } else {
	                     //   LOGGER.error("##### rowkey not found {}", rowkey);
	                    }*/
	                }
	                map.put("row",row );
	                dataLists.add(map);
	                rowNum++;

	            }
	            table.close();

其实这里主要就是对PageFilter的应用.

 

---------------------------------------------------------分割线-------------------------------

2019年8月20日补充:

现在贴上一个目前用的比较顺的分页+过滤的代码

/**
	 * 
	 * 
	 * @param tableName  表名
	 * @param filterList  过滤
	 * @param pageModel 一个实体类,
	 * @return
	 */
public HBasePageModel getPage(String tableName, FilterList filterList, HBasePageModel pageModel) {
		startRow = "";
		int pageSize = pageModel.getPageSize();//获取分页大小
		int pageNum = pageModel.getPageIndex();//获取当前页码

		// 设置list过滤
		if (filterList == null) {
			filterList = new FilterList();
		}
		log.info("过滤器信息::" + filterList.toString());
		long totalNum = 0L;
		Table table;
		List<Result> resultList = new ArrayList<Result>();

		// 获取总条数
		totalNum = HBaseTableDataUtil.getTotal(tableName, filterList);//这里使用的是协调器的方式进行获取的
		pageModel.setQueryTotalCount(totalNum);//把总记录数放进model中

		Filter page = new PageFilter(pageSize + 1);//分页设置
		filterList.addFilter(page);

		try {
			table = HBaseTableDataUtil.getTable(TableName.valueOf(tableName));//封装的获取table的方法
			// int totalSize = MyUtils.getTotal(filterList);
			Scan scan = new Scan();
			scan.setFilter(filterList);

			for (int i = 0; i < pageNum; i++) {
				ResultScanner rs = table.getScanner(scan);
				int count = 0;
				for (Result r : rs) {
					count++;
//这里是设置开始rowkey,不过这步我自己也没有看明白,本来打算去掉的,但是去掉以后有问题
					if (count == pageSize + 1) {
						startRow = new String(r.getRow());
						scan.setStartRow(startRow.getBytes());
						System.out.println("startRow" + startRow);
						break;
					}
					startRow = new String(r.getRow());

					// 在这一步判断是否到达我们需要的页面,是的话进行数据保存
					if (i == pageNum - 1) {
						resultList.add(r);
					}
				}
				if (count < pageSize) {
					break;
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
			log.error("getPage:::error:::" + e.getMessage());
		}

		pageModel.setResultList(resultList);
		return pageModel;
	}

HBasePageModel


import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hbase.client.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//这个是借用了其他人写的model
public class HBasePageModel implements Serializable{
	private static final Logger logger = LoggerFactory.getLogger(HBasePageModel.class);
	 private static final long serialVersionUID = 330410716100946538L;
	    private int pageSize = 25;
	    private int pageIndex = 0;
	    private int prevPageIndex = 1;
	    private int nextPageIndex = 1;
	    private int pageCount = 0;
	    private int pageFirstRowIndex = 1;
	    private byte[] pageStartRowKey = null;
	    private byte[] pageEndRowKey = null;
	    private boolean hasNextPage = true;
	    private long queryTotalCount = 0;
	    private long startTime = System.currentTimeMillis();
	    private long endTime = System.currentTimeMillis();
	    private List<Result> resultList = new ArrayList<Result>();
	    public HBasePageModel(int pageSize) {
	        this.pageSize = pageSize;
	    }
	    /**
	     * 获取分页记录数量
	     * @return
	     */
	    public int getPageSize() {
	        return pageSize;
	    }
	    /**
	     * 设置分页记录数量
	     * @param pageSize
	     */
	    public void setPageSize(int pageSize) {
	        this.pageSize = pageSize;
	    }
	    /**
	     * 获取当前页序号
	     * @return
	     */
	    public int getPageIndex() {
	        return pageIndex;
	    }
	    /**
	     * 设置当前页序号
	     * @param pageIndex
	     */
	    public void setPageIndex(int pageIndex) {
	        this.pageIndex = pageIndex;
	    }
	    /**
	     * 获取分页总数
	     * @return
	     */
	    public int getPageCount() {
	        return pageCount;
	    }
	    /**
	     * 设置分页总数
	     * @param pageCount
	     */
	    public void setPageCount(int pageCount) {
	        this.pageCount = pageCount;
	    }
	    /**
	     * 获取每页的第一行序号
	     * @return
	     */
	    public int getPageFirstRowIndex() {
	        this.pageFirstRowIndex = (this.getPageIndex() - 1) * this.getPageSize() + 1;
	        return pageFirstRowIndex;
	    }
	    /**
	     * 获取每页起始行键
	     * @return
	     */
	    public byte[] getPageStartRowKey() {
	        return pageStartRowKey;
	    }
	    /**
	     * 设置每页起始行键
	     * @param pageStartRowKey
	     */
	    public void setPageStartRowKey(byte[] pageStartRowKey) {
	        this.pageStartRowKey = pageStartRowKey;
	    }
	    /**
	     * 获取每页结束行键
	     * @return
	     */
	    public byte[] getPageEndRowKey() {
	        return pageEndRowKey;
	    }
	    /**
	     * 设置每页结束行键
	     * @param pageStartRowKey
	     */
	    public void setPageEndRowKey(byte[] pageEndRowKey) {
	        this.pageEndRowKey = pageEndRowKey;
	    }
	    /**
	     * 获取上一页序号
	     * @return
	     */
	    public int getPrevPageIndex() {
	        if(this.getPageIndex() > 1) {
	            this.prevPageIndex = this.getPageIndex() - 1;
	        } else {
	            this.prevPageIndex = 1;
	        }
	        return prevPageIndex;
	    }
	    /**
	     * 获取下一页序号
	     * @return
	     */
	    public int getNextPageIndex() {
	        this.nextPageIndex = this.getPageIndex() + 1;
	        return nextPageIndex;
	    }
	    /**
	     * 获取是否有下一页
	     * @return
	     */
	    public boolean isHasNextPage() {
	//这个判断是不严谨的,因为很有可能剩余的数据刚好够一页。
	        if(this.getResultList().size() == this.getPageSize()) {
	            this.hasNextPage = true;
	        } else {
	            this.hasNextPage = false;
	        }
	        return hasNextPage;
	    }
	    /**
	     * 获取已检索总记录数    
	     */
	    public long getQueryTotalCount() {
	        return queryTotalCount;
	    }
	    /**
	     * 获取已检索总记录数    
	     * @param queryTotalCount
	     */
	    public void setQueryTotalCount(long queryTotalCount) {
	        this.queryTotalCount = queryTotalCount;
	    }
	    /**
	     * 初始化起始时间(毫秒)
	     */
	    public void initStartTime() {
	        this.startTime = System.currentTimeMillis();
	    }
	    /**
	     * 初始化截止时间(毫秒)
	     */
	    public void initEndTime() {
	        this.endTime = System.currentTimeMillis();
	    }
	    /**
	     * 获取毫秒格式的耗时信息
	     * @return
	     */
	    public String getTimeIntervalByMilli() {
	        return String.valueOf(this.endTime - this.startTime) + "毫秒";
	    }
	    /**
	     * 获取秒格式的耗时信息
	     * @return
	     */
	    public String getTimeIntervalBySecond() {
	        double interval = (this.endTime - this.startTime)/1000.0;
	        DecimalFormat df = new DecimalFormat("#.##");
	        return df.format(interval) + "秒";
	    }
	    /**
	     * 打印时间信息
	     */
	    public void printTimeInfo() {
	    	logger.info("起始时间:" + this.startTime);
	    	logger.info("截止时间:" + this.endTime);
	    	logger.info("耗费时间:" + this.getTimeIntervalBySecond());
	    }
	    /**
	     * 获取HBase检索结果集合
	     * @return
	     */
	    public List<Result> getResultList() {
	        return resultList;
	    }
	    /**
	     * 设置HBase检索结果集合
	     * @param resultList
	     */
	    public void setResultList(List<Result> resultList) {
	        this.resultList = resultList;
	    }
}

getTotal()   //统计条数

  public static long getTotal(String tableName,FilterList filterList){
    	long num = 0;
    	AggregationClient aggregationClient = new AggregationClient(getConfig());
           try {
        	   Scan scan = new Scan();
        	   if(filterList.getFilters().size() > 0)
        		   scan.setFilter(filterList);
        	   scan.setMaxVersions(1);
               Long rowCount = aggregationClient.rowCount(TableName.valueOf(tableName),
                       new LongColumnInterpreter(), scan);
               aggregationClient.close();
               num = rowCount.intValue();
           } catch (Throwable e) {
               e.printStackTrace();
           }
           return num;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值