一、 实验目的
1)理解 HBase 在 Hadoop 体系结构中的角色。
2)熟练使用 HBase 操作常用的 shell 命令。
3)熟悉 HBase 操作常用的 Java API。
二、 实验平台
1)操作系统:Linux(Ubuntu18.04);
2)Hadoop 版本:2.9.0;
3)HBase 版本:1.2.6;
4)JDK 版本:1.8;
5)Java IDE:Eclipse 3.8。
三、 实验内容
1)编程实现以下指定功能,并用 Hadoop 提供的 HBase Shell 命令完成相同任务: (1) 列出 HBase 所有的表的相关信息,例如表名; (2) 在终端打印出指定的表的所有记录数据; (3) 向已经创建好的表添加和删除指定的列族或列; (4) 清空指定的表的所有记录数据; (5) 统计表的行数。
2)HBase 数据库操作
3)请编程实现以下功能:
createTable(String tableName, String[] fields) 创建表,参数 tableName 为表的名称,字符串数组 fields 为存储记录各个字段名称的数组。 要求当 HBase 已经存在名为 tableName 的表的时候,先删除原有的表,然后再创建新的表。 addRecord(String tableName, String row, String[] fields, String[] values) 向表 tableName、行 row(用 S_Name 表示)和字符串数组 fields 指定的单元格中添加对应 的数据 values。其中,fields 中每个元素如果对应的列族下还有相应的列限定符的话,用 “columnFamily:column”表示。例如,同时向“Math”、“Computer Science”、“English”三列添加成绩时,
字符串数组 fields 为{“Score:Math”, ”Score:Computer Science”, ”Score:English”},数组 values 存储这 三门课的成绩。
scanColumn(String tableName, String column) 浏览表 tableName 某一列的数据,如果某一行记录中该列数据不存在,则返回 null。要求 当参数 column 为某一列族名称时,如果底下有若干个列限定符,则要列出每个列限定符代表的列 的数据;当参数 column 为某一列具体名称(例如“Score:Math”)时,只需要列出该列的数据。 modifyData(String tableName, String row, String column) 修改表 tableName,行 row(可以用学生姓名 S_Name 表示),列 column 指定的单元格的 数据。
deleteRow(String tableName, String row) 删除表 tableName 中 row 指定的行的记录。
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.*;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
public class hbasetest {
public static Configuration configuration;
public static Connection connection;
public static Admin admin;
public static void main(String[] args) throws IOException {
String[] fields = { "Name", "Score"};
createTable("test",fields);//创建表
put("test","row1","Name","","gagaga");//添加列族
put("test","row1","Score","English","95");//添加列
put("test","row1","Score","Math","100");
put("test","row1","Score","CS","90");
put("test","row2","Name","","wawawa");//添加列族
scanColumn("test","Score");
modifyData("test","row1","Name","hahaha");
list();//列出所有表的表名
scan("test");//打印指定表的所有记录数据
delete("test","row1","Score","Math",2);//删除列
scan("test");
delete("test","row1","Score","",1);//删除列族
scan("test");
deleteRow("test","row1");
count("test");//统计表的行数
truncate("test");//清空制定表的所有记录数据
count("test");
//第四部分 HBase 先在shell清空'Student'
put("Student", "row_01", "Name", "", "scofield");
put("Student", "row_01", "Score", "English", "45");
put("Student", "row_01", "Score", "Math", "89");
put("Student", "row_01", "Score", "Computer", "100");
get("Student", "row_01","Score","English");
}
// 建立连接
public static void init() throws IOException {
configuration = HBaseConfiguration.create();
configuration.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
}
// 关闭连接
public static void close() throws IOException {
if (admin != null) {
admin.close();
}
if (connection != null) {
connection.close();
}
}
// 列出HBase所有的表的相关信息,例如表名
public static void list() throws IOException {
init();
System.out.println("打印所有表的相关信息,以表名为例:");
HTableDescriptor htds[] = admin.listTables();//列出所有用户控件表项
for (HTableDescriptor htd : htds) {
System.out.println(htd.getNameAsString());
}
close();
}
// 在终端打印出指定的表的所有记录数据;
public static void scan(String tablename) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tablename));
Scan s = new Scan();
ResultScanner scanner = table.getScanner(s);
System.out.println("打印表" + tablename + "的所有信息:");
for (Result result : scanner) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
System.out.println("rowKey: " + new String(CellUtil.cloneRow(cell)));
System.out.println("colFamily: " + new String(CellUtil.cloneFamily(cell)));
System.out.println("clomn: " + new String(CellUtil.cloneQualifier(cell)));
System.out.println("timesTamp: " + cell.getTimestamp());
System.out.println("value: " + new String(CellUtil.cloneValue(cell)));
}
}
close();
}
// 向已经创建好的表添加指定的列族或列
public static void put(String tablename, String rowKey, String colFamily, String colmn, String value)
throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tablename));
Put p = new Put(rowKey.getBytes());
p.addColumn(colFamily.getBytes(), colmn.getBytes(), value.getBytes());
table.put(p);
table.close();
close();
}
// 向已经创建好的表删除指定的列族或列
public static void delete(String tablename, String rowKey, String colFamily, String colmn, int flag)
throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tablename));
Delete del = new Delete(rowKey.getBytes());
if (flag == 1) {
// flag为1,删除指定列族的所有数据
del.addFamily(colFamily.getBytes());
table.delete(del);
} else {
// flag为2,删除指定列的数据
del.addColumn(colFamily.getBytes(), colmn.getBytes());
table.delete(del);
}
table.close();
close();
}
// 清空指定的表的所有记录数据
public static void truncate(String tableName)
throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
init();
// 保存表的架构,重建时用
HTableDescriptor htd = admin.getTableDescriptor(TableName.valueOf(tableName));
TableName tablename = TableName.valueOf(tableName);
// 关闭表
admin.disableTable(tablename);
// 删除表
admin.deleteTable(tablename);
// 重建表
admin.createTable(htd);
close();
}
// 统计表的行数
public static void count(String tablename) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tablename));
Scan s = new Scan();
ResultScanner scanner = table.getScanner(s);
int num = 0;
for (Result result : scanner) {
if (result != null) {
num++;
}
}
System.out.println("行数为:" + num);
close();
}
// 创建表,参数 tableName 为表的名称,字符串数组 fields 为存储记录各个字段名称的数组。
// 要求当 HBase 已经存在名为 tableName 的表的时候,先删除原有的表,然后再创建新的表。
public static void createTable(String tableName, String[] fields) throws IOException {
init();
TableName tablename = TableName.valueOf(tableName);
if (admin.tableExists(tablename)) {
System.out.println("表已经存在,删除原有表,创建新表");
admin.disableTable(tablename);
admin.deleteTable(tablename);
}
HTableDescriptor htd = new HTableDescriptor(tablename);
for (String str : fields) {
HColumnDescriptor hcd = new HColumnDescriptor(str);
htd.addFamily(hcd);
}
admin.createTable(htd);
close();
}
// 向表 tableName、行 row(用 S_Name 表示)和字符串数组 fields 指定的单元格中添加对应的数据 values。
// 其中,fields 中每个元素如果对应的列族下还有相应的列限定符的话,用 “columnFamily:column”表示。
public static void addRecord(String tableName, String row, String[] fields, String[] values) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
for (int i = 0; i < fields.length; i++) {
Put p = new Put(row.getBytes());
String[] cols = fields[i].split(":");
if (cols.length == 1) {
p.addColumn(cols[0].getBytes(), "".getBytes(), values[i].getBytes());
} else {
p.addColumn(cols[0].getBytes(), cols[1].getBytes(), values[i].getBytes());
}
table.put(p);
}
table.close();
close();
}
// 浏览表 tableName 某一列的数据,如果某一行记录中该列数据不存在,则返回 null。
// 要求 当参数 column 为某一列族名称时,如果底下有若干个列限定符,则要列出每个列限定符代表的列的数据;
// 当参数 column 为某一列具体名称(例如“Score:Math”)时,只需要列出该列的数据。
public static void scanColumn(String tableName, String column) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
String[] cols = column.split(":");
if (cols.length == 1) {
scan.addFamily(Bytes.toBytes(column));
} else {
scan.addColumn(Bytes.toBytes(cols[0]), Bytes.toBytes(cols[1]));
}
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
System.out.println("rowKey: " + new String(CellUtil.cloneRow(cell)));
System.out.println("colFamily: " + new String(CellUtil.cloneFamily(cell)));
System.out.println("clomn: " + new String(CellUtil.cloneQualifier(cell)));
System.out.println("timesTamp: " + cell.getTimestamp());
System.out.println("value: " + new String(CellUtil.cloneValue(cell)));
}
}
table.close();
close();
}
// 修改表 tableName,行 row(可以用学生姓名 S_Name 表示),列 column 指定的单元格的数据
public static void modifyData(String tableName, String row, String column, String val) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Put p = new Put(row.getBytes());
String[] cols = column.split(":");
if (cols.length == 1) {
p.addColumn(column.getBytes(), "".getBytes(), val.getBytes());
} else {
p.addColumn(cols[0].getBytes(), cols[1].getBytes(), val.getBytes());
}
table.put(p);
table.close();
close();
}
// 删除表tableName中row指定的行的记录。
public static void deleteRow(String tableName, String row) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(row.getBytes());
table.delete(delete);
table.close();
close();
}
// 查询指定单cell内容
public static void get(String tableName, String rowKey, String family, String col)throws IOException{
init();
Table table = connection.getTable(TableName.valueOf(tableName));
String result = null;
Get get = new Get(rowKey.getBytes());
if(!get.isCheckExistenceOnly()){
get.addColumn(Bytes.toBytes(family),Bytes.toBytes(col));
Result res = table.get(get);
byte[] resByte = res.getValue(Bytes.toBytes(family), Bytes.toBytes(col));
result = Bytes.toString(resByte);
System.out.print(result);
}
close();
}
}