实验平台
操作系统: Ubuntu 18.04.4LTS
Hadoop 版本: 2.7.7
HBase 版本:2.0.5
JDK 版本: 1.8.0_241
Java IDE: Eclipse
安装包:
HBase:https://archive.apache.org/dist/hbase/2.0.5/
实验内容
(一) 编程实现以下指定功能,并用 Hadoop 提供的 HBase Shell 命令完成相同任务:
(1) 列出 HBase 所有的表的相关信息,例如表名;
(2) 在终端打印出指定的表的所有记录数据;
(3) 向已经创建好的表添加和删除指定的列族或列;
(4) 清空指定的表的所有记录数据;
(5) 统计表的行数。
package shiyan4;
import java.io.IOException;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
public class shiyan4_1 {
// 对配置信息管理的一个类
public static Configuration configuration;
// 对连接进行管理的一个类
public static Connection connection;
// 对数据库进行管理的一个类,用于对表的增删改查
public static Admin admin;
//建立连接
public static void init() {
configuration = HBaseConfiguration.create();
configuration.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
try {
// 获取连接池
connection = ConnectionFactory.createConnection(configuration);
// 使用连接对象获取Admin对象
admin = connection.getAdmin();
} catch(IOException e) {
e.printStackTrace();
}
}
//关闭连接
public static void close( ) {
try {
if(admin != null) {
admin.close();
}
if(null != connection) {
connection.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
//列出HBase所有的表
public static void listTables() throws IOException
{
HTableDescriptor[] hTableDescriptors = admin.listTables();
for (HTableDescriptor hTableDescriptor : hTableDescriptors)
{
System.out.println("表名:" + hTableDescriptor.getNameAsString());
}
}
//在终端打印出指定的表的所有记录数据
public static void getData(String tableName) throws IOException
{
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
for(Result result : scanner) //获取的result数据是结果集
{
printRecoder(result);
}
}
public static void printRecoder(Result result) throws IOException
{
for (Cell cell : result.rawCells())
{
System.out.print("行键:" + new String(CellUtil.cloneRow(cell)) + " ");
System.out.print("列族: " + new String(CellUtil.cloneFamily(cell))+" ");
System.out.print(" 列: " + new String(CellUtil.cloneQualifier(cell))+" ");
System.out.print(" 值: " + new String(CellUtil.cloneValue(cell))+" ");
System.out.println("时间戳: " + cell.getTimestamp());
}
}
//向已经创建好的表添加指定的的列族或列
public static void insertRow(String tableName, String rowKey, String colFamily, String col, String val) throws IOException
{
Table table = connection.getTable(TableName.valueOf(tableName));
Put put = new Put(rowKey.getBytes());
put.addColumn(colFamily.getBytes(), col.getBytes(), val.getBytes());
table.put(put);
table.close();
}
//向已经创建好的表删除指定的列族或列
public static void deleteRow(String tableName, String rowKey, String colFamily, String col) throws IOException
{
Table table = connection.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(rowKey.getBytes());
delete.addFamily(Bytes.toBytes(colFamily));
delete.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col));
table.delete(delete);
table.close();
}
//清空指定的表的所有记录数据
public static void clearRows(String tableName) throws IOException
{
TableName tablename = TableName.valueOf(tableName);
admin.disableTable(tablename);
admin.truncateTable(tablename, false);
}
//统计表的行数
public static void countTable(String tableName) throws IOException
{
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
int cnt = 0;
for(Result result = scanner.next(); result != null; result = scanner.next())
{
cnt++;
}
System.out.println("行数:" + cnt);
scanner.close();
}
//主函数
public static void main(String[] args)
{
try
{
int n = 0;
init();
Scanner in = new Scanner(System.in);
while(n != 7)
{
System.out.println("1.列出 Hbase 所有的表的信息");
System.out.println("2.在终端打印出指定表的所有记录数据");
System.out.println("3.向已经创建好的表添加指定的的列族或列");
System.out.println("4.向已经创建好的表删除指定的的列族或列");
System.out.println("5.清空指定的表的所有记录数据");
System.out.println("6.统计表的行数");
System.out.println("7.退出");
System.out.println("请选择:");
if(in.hasNextInt())
{
n = in.nextInt();
}
else
{
System.out.println("输入的不是整数,请重新输入:");
continue;
}
switch(n)
{
case 1:
listTables();
break;
case 2:
getData("Student");
break;
case 3:
insertRow("tempTable", "r1", "f1", "c1", "hello,dblab");
break;
case 4:
deleteRow("tempTable", "r1", "f1", "c1");
break;
case 5:
clearRows("tempTable");
break;
case 6:
countTable("tempTable");
break;
case 7:
break;
default:
System.out.println("输入错误,请重新输入");
}
}
close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
(二) HBase 数据库操作
2. 请编程实现以下功能:
(1) createTable(String tableName, String[] fields)
创建表,参数 tableName 为表的名称,字符串数组 fields 为存储记录各个字段名称的数组。要求当 HBase 已经存在名为 tableName 的表的时候,先删除原有的表,然后再创建新的表。
(2) 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 存储这三门课的成绩。
(3) scanColumn(String tableName, String column)
浏览表 tableName 某一列的数据,如果某一行记录中该列数据不存在,则返回 null。要求当参数 column 为某一列族名称时,如果底下有若干个列限定符,则要列出每个列限定符代表的列的数据;当参数 column 为某一列具体名称(例如“Score:Math”)时,只需要列出该列的数据。
(4) modifyData(String tableName, String row, String column)
修改表 tableName,行 row(可以用学生姓名 S_Name 表示),列 column 指定的单元格的数据。
(5) deleteRow(String tableName, String row)
删除表 tableName 中 row 指定的行的记录。
package shiyan4;
import java.io.IOException;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
public class shiyan4_2_2 {
// 对配置信息管理的一个类
public static Configuration configuration;
// 对连接进行管理的一个类
public static Connection connection;
// 对数据库进行管理的一个类,用于对表的增删改查
public static Admin admin;
//建立连接
public static void init() {
configuration = HBaseConfiguration.create();
configuration.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
try {
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
} catch(IOException e) {
e.printStackTrace();
}
}
//关闭连接
public static void close( ) {
try {
if(admin != null) {
admin.close();
}
if(null != connection) {
connection.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
//创建表,参数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”表示。
//例如,同时向“Math”、 “Computer Science”、 “English”三列添加成绩时,
//字符串数组 fields 为{“Score:Math”, ”Score:Computer Science”, ”Score:English”},
//数组 values 存储这三门课的成绩。
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("行键:" + new String(CellUtil.cloneRow(cell)));
System.out.println("列族: " + new String(CellUtil.cloneFamily(cell)));
System.out.println("列限定符: " + new String(CellUtil.cloneQualifier(cell)));
System.out.println("时间戳: " + cell.getTimestamp());
System.out.println("数据: " + 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();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
shiyan4_2_2 shiyan = new shiyan4_2_2();
try
{
//1
System.out.println("执行1:");
String[] fields1 = {"Score", "Sage"}; //存储记录各个字段名称的数组
shiyan.createTable("S_Info", fields1);
//2
System.out.println("执行2:");
String[] fields2 = {"Score:Math", "Score:Computer Science", "Score:English"};
String[] values2 = {"90", "88.5", "59.5"};
shiyan.addRecord("S_Info", "S_Name", fields2, values2);
//3
System.out.println("执行3:");
shiyan.scanColumn("S_Info", "Score");
shiyan.scanColumn("S_Info", "Score:Math");
//4
System.out.println("执行4:");
shiyan.modifyData("S_Info", "S_Name", "Score:English", "60");
shiyan.scanColumn("S_Info", "Score:English");
//5
System.out.println("执行5:");
shiyan.deleteRow("S_Info", "S_Name");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}