HBase表管理系统


1. 软件版本 & 部署:

maven3.3.9jdk1.7 Struts22.3.24.1hibernate4.3.6spring4.2.5MySQL5.1.34Junit4Myeclipse2014

Hadoop2.6.4HBase1.1.2

源码下载: https://github.com/fansy1990/ssh_v3/releases

部署参考: http://blog.csdn.net/fansy1990/article/details/51356583

2. 系统功能及核心实现

2.1系统菜单

HBase表管理系统主要是对表以及表数据的相关操作;

2.2 表管理

直接打开Table管理界面,即可看到所有表的简要信息,包括数据库namspace)、表名、简单表描述等;

这个查询的信息直接基于AdminlistTableNames方法,具体调用如下:

<span style="color:#555555;">/**</span>
 * 获取所有表
 * 
 * @return
 * @throws IOException
 */
public List<HBaseTable> getTables() throws IOException {
List<HBaseTable> list = new ArrayList<>();
Admin admin = HadoopUtils.getHBaseConnection().getAdmin();
TableName[] tables = admin.listTableNames();
HBaseTable hTable = null;
 
for (TableName t : tables) {
hTable = new HBaseTable();
hTable.setNameSpace(t.getNamespaceAsString());
hTable.setTableName(t.getNameAsString());
// HTableDescriptor htableDes = admin.getTableDescriptor(t);
// System.out.println(htableDes.toString());
// System.out.println(htableDes.toStringTableAttributes());
// System.out.println(htableDes.getFamilies().toString());
// System.out.println(htableDes.toStringCustomizedValues());
hTable.setDescription(admin.getTableDescriptor(t)
.toStringCustomizedValues());
setRegions(hTable, admin.getTableRegions(t));
list.add(hTable);
}
 
return list;
}
2.2.1 表详细

表详细功能需要先选定一行记录,否则会提示:

选择一个记录后,点击表详细即可弹出表详细信息:

后台实现通过admin.getTableDescriptor即可获得表的详细信息,但是需要提供表名,表名可以从前天传入即可,如下:

<span style="color:#555555;">/**</span>
 * 获取指定表详细信息
 * 
 * @param tableName
 * @return
 * @throws IOException
 */
public String getTableDetails(String tableName) throws IOException {
Admin admin = HadoopUtils.getHBaseConnection().getAdmin();
HTableDescriptor tableDescriptors = admin
.getTableDescriptor(getTableName(tableName));
System.out.println(tableDescriptors.toStringCustomizedValues());
System.out.println(tableDescriptors.toString());
return admin.getTableDescriptor(getTableName(tableName)).toString();
}
2.2.2 表新增

表新增功能只是提供一个简单的新增,即只提供表名、列簇名即可,如下:

同时提交后台后,如果表已经存在则会进行对应的提示,后台通过遍历所有表名实现此功能,效率不高,实现如下:

<span style="color:#555555;">public</span><span style="color:#555555;"> boolean</span> checkTableExists(String tableName) throws IOException {
Admin admin = HadoopUtils.getHBaseConnection().getAdmin();
TableName[] tables = admin.listTableNames();
for (TableName t : tables) {
if (t.getNameAsString().equals(tableName)) {
return true;
}
}
return false;
}

新增表,通过admincreateTable实现:

<span style="color:#555555;">public</span><span style="color:#555555;"> boolean</span> saveTable(String tableName, String cfs) throws IOException {
Admin admin = HadoopUtils.getHBaseConnection().getAdmin();
HTableDescriptor hTableDescriptor = new HTableDescriptor(
getTableName(tableName));
String[] cfsArr = StringUtils.split(cfs, Utils.COMMA);
for (String cf : cfsArr) {
hTableDescriptor.addFamily(new HColumnDescriptor(cf));
}
admin.createTable(hTableDescriptor);
return true;
}
2.2.3 表删除

表删除,同样需要选择一条记录,如果没有选择记录,同样会提示选择表,选择表后,点击删除,会进行下面的提示:

如果点击OK,则删除,Cancel则取消;

删除实现,同样使用AdmindisableTable, deleteTable方法

<span style="color:#555555;">public</span><span style="color:#555555;"> boolean</span> deleteTable(String tableName) throws IOException {
Admin admin = HadoopUtils.getHBaseConnection().getAdmin();
admin.disableTable(getTableName(tableName));
admin.deleteTable(getTableName(tableName));
return true;
}

备注:这里应该先判断此表是否是enable状态,如果不是则直接删除;如果是disable状态,则执行上述代码会有问题;

2.3 表数据管理

在打开表数据管理页面后,会初始化表名的下拉框,下拉框中数据的获取采用AJax的方式访问后台获取,方法同样使用AdminlistTableNames方法;

在选择一个表后,会初始化列簇名下拉框数据和start rowkey ,如下:

在查询数据时,可以选择多个列簇名,同时可以修改Start rowkey ,选择记录数以及版本数;

根据表名获取列簇名后台代码实现如下(通过HTableDescriptorgetColumnFamilies方法获取):

<span style="color:#555555;">public</span><span style="color:#555555;"> List</span><TextValue> getTablesColumnFamily(String tableName)
throws IOException {
List<TextValue> list = new ArrayList<>();
Admin admin = HadoopUtils.getHBaseConnection().getAdmin();
HTableDescriptor tableDescriptor = admin
.getTableDescriptor(getTableName(tableName));
HColumnDescriptor[] columnDescriptors = tableDescriptor
.getColumnFamilies();
for (HColumnDescriptor t : columnDescriptors) {
list.add(new TextValue(t.getNameAsString()));
}
return list;
}

以及start rowKey的后台代码如下(即,只读取第一行数据,然后返回其rowkey):

<span style="color:#555555;">public</span><span style="color:#555555;"> String getTableRowKey(String tableName) throws</span> IOException {
Table table = HadoopUtils.getHBaseConnection().getTable(
getTableName(tableName));
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
Result firstRow = scanner.next();
scanner.close();
table.close();
if (firstRow == null)
return "-1";
 
return new String(firstRow.getRow());
}

根据表名、列簇名、start rowkey、版本数、记录数,获取数据的后台代码如下:

<span style="color:#555555;">public</span><span style="color:#555555;"> List<HBaseTableData> getTableData(String tableName, String cfs,</span>
String startRowKey, int limit, int versions) throws IOException {
List<HBaseTableData> datas = new ArrayList<>();
Table table = HadoopUtils.getHBaseConnection().getTable(
getTableName(tableName));
Scan scan = new Scan();
scan.setMaxVersions(versions);
if (startRowKey != "-1") {
scan.setStartRow(startRowKey.getBytes());
}
String[] cfsArr = cfs.split(Utils.COMMA, -1);
for (String cf : cfsArr) {
scan.addFamily(cf.getBytes());
}
 
ResultScanner scanner = table.getScanner(scan);
 
Result[] rows = scanner.next(limit);
 
for (Result row : rows) {
// Cell[] cells = row.rawCells();
 
datas.addAll(getFromCells(row.rawCells()));
}
 
scanner.close();
table.close();
return datas;
}

通过设置ScanmaxVersions以及startRow 来限定版本数和开始遍历位置,通过设置scanner.next来限定获取的记录数;

3.1 新增

数据新增,通过指定表名、列簇名即可,如果列簇名指定多个,会提示错误:

数据新增使用window弹出框,为了把表名和列簇名传递到该window,使用了url加参数的方法(比较别扭的方式),具体如下:

<span style="color:#555555;">var win_table_add_data_ = $('#win_table_add_data').window({    </span>
    width:450,    
    height:350,    
    modal:true,
    left:400,
    top:150,
    title:'数据新增',
    collapsible:false,
    minimizable:false,
    maximizable:false,
//          content: '<div style="padding:30px 20px 10px 20px;">' + "a" +'</div>'
    content: '<iframe id="tabIframe" src="hbaseCommand/data_add.jsp?tableName='+tableName_+'&cf='+cf_+
        '"frameborder="0"style="border:0;width:100%;height:100%;">',
//          href:"hbaseCommand/data_add.jsp",
    onOpen:function(){    
        // 修改对应的值;
//              $('#data_add_ff_tableName').val(getFakeData('cc_data_retrieve_tableName'));
//              $('#data_add_ff_family').val(cf_);  
//              $('#data_add_ff_family').textbox('setValue',cf_);  
    
    }
 
});

在弹出框中,用户可以输入rowkey,column,vlaue

表名、列簇名不可编辑,用户点击添加后,直接put数据到表中;

<span style="color:#555555;">public</span><span style="color:#555555;"> boolean saveTableData(String tableName, String cfs, String rowkey,</span>
String column, String value) throws IOException {
Table table = HadoopUtils.getHBaseConnection().getTable(
getTableName(tableName));
Put put = new Put(Bytes.toBytes(rowkey));
put.addColumn(Bytes.toBytes(cfs), Bytes.toBytes(column),
Bytes.toBytes(value));
 
table.put(put);
table.close();
return true;
}
3.3.2数据删除

直接根据提供的数据使用checkAndDelete进行删除,防止在删除的时候数据被修改:

<span style="color:#555555;">public boolean deleteTableData(String tableName, String family,</span>
String qualifier, String rowkey, String value, long timestamp)
throws IOException {
Table table = HadoopUtils.getHBaseConnection().getTable(
getTableName(tableName));
Deletedelete = new Delete(Bytes.toBytes(rowkey));
delete.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier),
timestamp);
boolean flag = table.checkAndDelete(Bytes.toBytes(rowkey),
Bytes.toBytes(family), Bytes.toBytes(qualifier),
Bytes.toBytes(value), delete);
 
table.close();
 
return flag;
}
3.3.3 数据更新

数据更新,同样需要选择一条记录,弹出框的方式类似数据新增(比较别扭的方式),不过可修改的内容只有值而已:

除了值之外,其他输入框都是只读的;后台实现,同样使用checkAndPut 方法:

<span style="color:#555555;">public</span><span style="color:#555555;"> boolean updateTableData(String tableName, String cfs, String rowkey,</span>
String column, String value, long timestamp, String oldValue)
throws IOException {
Table table = HadoopUtils.getHBaseConnection().getTable(
getTableName(tableName));
Put put = new Put(Bytes.toBytes(rowkey));
put.addColumn(Bytes.toBytes(cfs), Bytes.toBytes(column), timestamp,
Bytes.toBytes(value));
 
table.checkAndPut(Bytes.toBytes(rowkey), Bytes.toBytes(cfs),
Bytes.toBytes(column), Bytes.toBytes(oldValue), put);
table.close();
return true;
}

4. 总结

1HBase的相关API的使用不是很难,主要是如果是插入或者更新操作,需要保持记录前后一致,需要进行row lock,这时就需要用到checkAndXxx 操作了,具体可以参考: http://blog.csdn.net/fansy1990/article/details/51451583 

2数据新增和数据更新弹出框的方式比较别扭,可以考虑使用新的方式(因为要进行参数的传递);

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值