背景
HBase在處理billion級別的能力是毫無質疑的,目前優于其他的nosql數據庫,如mongodb、cassandra、redis等, 配合它強大的rowkey查詢,fileter,協處理器等,在海量數據庫中發揮了強大的功能。但是HBase因為滿足的是CAP原則中C和P,所以在查詢過程中語句支持較弱,使用過程較為復雜。存在下面的一些痛點。
痛點 首先HBase只能
存儲byte數組的數據,數據存入到hbase中時都需要做相應的轉換,讀取的數據的時候也要相應的轉換回來,使用麻煩。
第二,HBase在使用過程中,涉及到filter、協處理的使用,如果對API不熟悉,無法下手。
第三,hbase本身不提供分頁的功能,每次分頁需要在代碼中記錄當前讀取的rowkey,在使用PageFilter讀取一定數量的rowkey,然后繼續讀取,編程復雜度高。
最后,不熟悉hbase的開發人員,無法理解nosql、hbase的no schema,期望還是用關系數據庫的方式操作hbase。
HBase ORM框架
基于以上的原因,所以我有了想寫一個類似于hibernate那種對象關系映射框架(ORM)的想法,像操作對象一樣方便的操作HBase數據庫,但是它要是輕量級的,無侵入的,只提供CURD、分頁、映射功能的一個簡單功能。
一些特性:
使用注解的方式,將PO(Persistent Object)映射成HBase對應的表
提供CRUD的方法:create
esearchupdatedelete
提供分頁查詢的功能
提供類似于hibernate中Criteria 風格的操作方式
Demo:
1、在po對象上添加相應的注解:@Table@RowKey@Column
@Table(name = "user")
public class User {
@RowKey
private int id;
@Column(family = "info")
private int userId;
@Column(family = "info", name = "user_name1")
private String userName;
@Column(family = "info")
private long age;
2、使用HBaseColumnarClient實例操作PO對象
" hljs axapta"> HBaseColumnarClient client = new HBaseColumnarClient(scanCaching, scanBatch);
DataSourceConfig config = new DataSourceConfig("hbase.properties");
HBaseSource source = new HBaseSource(config.getProperties());
client.setHBaseSource(source);
//create
client.putObject(user);
//delete
client.deleteObject(user);
//query
User user = client.findObject(Bytes.toBytes(1), User.class);
3、提供類似于Hibernate Criteria的風格操作hbase
// count the data
Filter[] filters = null;
long count =
Criteria.aggregate(User.class).fromRow(startRow).toRow(endRow)
.filters(filters).build().count(client);
// sum the column value
long sum =
Criteria.aggregate(User.class).fromRow(startRow).toRow(endRow)
.filters(filters).propertyName("age").build().sum(client);
// query by rowKey
User queryUser =
Criteria.find(User.class).byRowKey(Bytes.toBytes(id)).build().query(client);
// query from startRow to endRow
List
queryList =
Criteria.find(User.class).fromRow(startRow).toRow(endRow).build()
.queryList(client);
// query by page
PageBean pageBean = new PageBean() {};
pageBean.setPageSize(10);
pageBean.setStartRow(startRow);
pageBean.setStopRow(endRow);
PageBean queryPage =
Criteria.find(User.class).pageBean(pageBean).build().queryPage(client);
// delete data
byte[] rowKey = Bytes.toBytes(id);
Criteria.delete(User.class).byRowKey(rowKey).build().excute(client);