实验3 熟悉常用的HBase操作

一、实验目的

  1. 理解HBase在Hadoop体系结构中的角色;
  2. 熟练使用HBase操作常用的shell命令;
  3. 熟悉HBase操作常用的Java API;

二、实验平台

  1. 操作系统:Linux;
  2. Hadoop版本:3.1.3;
  3. HBase版本:2.2.2;
  4. JDK版本:1.8;
  5. Java IDE:Eclipse。

三、实验步骤

(一)编程实现以下指定功能,并利用Hadoop提供的HBase Shell命令完成相同任务; 

  1. 列出HBase所有的表的相关新信息,例如表名;
    //列出HBase所有的表的相关信息,例如表名、创建时间等
    	public static void listTables() throws IOException {
    		init();//建立连接
    		List<TableDescriptor> tableDescriptors = admin.listTableDescriptors();
    		for (TableDescriptor tableDescriptor : tableDescriptors) {
    			TableName tableName = tableDescriptor.getTableName();
    			System.out.println("Table:"+tableName);
    		}
    		close();//关闭连接
    	}	
  2. 在终端打印出指定的表的所有记录数据
    //在终端打印出指定的表的所有记录数据
    	public static void getData(String tableName) throws IOException {
    		init();
    		Table table = connection.getTable(TableName.valueOf(tableName));
    		Scan scan = new Scan();
    		ResultScanner scanner = table.getScanner(scan);//获取行的遍历器
    		for (Result result:scanner) {
    			printRecoder(result);
    		}
    		close();
    	}
    	
    	//打印一条记录的详情
    	private static void printRecoder(Result result) {
    		// TODO Auto-generated method stub
    		for(Cell cell:result.rawCells()) {
    			String str1 = Bytes.toString(cell.getRowArray(),cell.getRowOffset(),cell.getRowLength());
    			System.out.println("行键:"+ str1);
    			String str2 = Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength());
    			System.out.println("列簇:" + str2);
    			String str3 = Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength());
    			System.out.println("列:" + str3);
    			String str4 = Bytes.toString(cell.getValueArray(),cell.getValueOffset(),cell.getValueLength());
    			System.out.println("值:" + str4);
    			System.out.println("时间戳:" + cell.getTimestamp());
    		}
    	}

  3. 向已经创建好的表添加和删除指定的列簇或列
    //向已经创建好的表添加和删除指定的列簇或列
    	
    	//向表添加数据
    	public static void insterRow(String tableName,String rowKey,String colFamily,String col,String val) throws IOException {
    		init();
    		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();
    		close();
    	}
    	
    	//删除数据
    	public static void deleRow(String tableName,String rowKey,String colFamily,String col) throws IOException {
    		init();
    		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();
    		close();
    	}

  4. 清空指定的表的所有记录数据
    //清空指定的表的所有记录数据
    	public static void clearRows(String tableName) throws IOException {
    		init();
    		TableName tablename = TableName.valueOf(tableName);
    		admin.disableTable(tablename);
    		System.out.println("disable...delete...");
    		admin.deleteTable(tablename);
    		System.out.println("delete...over...create");
    		TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tablename);
    		ColumnFamilyDescriptor colFamilyDes=ColumnFamilyDescriptorBuilder.newBuilder(" ".getBytes()).build();
    		tableDescriptor.setColumnFamily(colFamilyDes).build();
    		admin.createTable(tableDescriptor.build());
    		
    		close();
    	}

  5. 统计表的行数
    //统计表的行数
    	public static void countRows(String tableName) throws IOException {
    		init();
    		Table table = connection.getTable(TableName.valueOf(tableName));
    		Scan scan = new Scan();
    		ResultScanner scanner = table.getScanner(scan);
    		int num = 0;
    		for (Result result = scanner.next();result!=null;result=scanner.next()) {
    			num++;
    		}
    		System.out.println("行数:" + num);
    		scanner.close();
    		close();
    	}

    以上的全部代码:

    import java.io.IOException;
    import java.util.List;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.client.*;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.apache.hadoop.hbase.*;
    
    public class Test {
    	
    	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) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    	
    	//关闭连接
    	public static void  close() {
    		try {
    			if (admin != null) {
    				admin.close();
    			}
    			if (null != connection) {
    				connection.close();
    			}
    		} catch (IOException e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    	
    	//列出HBase所有的表的相关信息,例如表名、创建时间等
    	public static void listTables() throws IOException {
    		init();//建立连接
    		List<TableDescriptor> tableDescriptors = admin.listTableDescriptors();
    		for (TableDescriptor tableDescriptor : tableDescriptors) {
    			TableName tableName = tableDescriptor.getTableName();
    			System.out.println("Table:"+tableName);
    		}
    		close();//关闭连接
    	}
    	
    	//在终端打印出指定的表的所有记录数据
    	public static void getData(String tableName) throws IOException {
    		init();
    		Table table = connection.getTable(TableName.valueOf(tableName));
    		Scan scan = new Scan();
    		ResultScanner scanner = table.getScanner(scan);//获取行的遍历器
    		for (Result result:scanner) {
    			printRecoder(result);
    		}
    		close();
    	}
    	
    	//打印一条记录的详情
    	private static void printRecoder(Result result) {
    		// TODO Auto-generated method stub
    		for(Cell cell:result.rawCells()) {
    			String str1 = Bytes.toString(cell.getRowArray(),cell.getRowOffset(),cell.getRowLength());
    			System.out.println("行键:"+ str1);
    			String str2 = Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength());
    			System.out.println("列簇:" + str2);
    			String str3 = Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength());
    			System.out.println("列:" + str3);
    			String str4 = Bytes.toString(cell.getValueArray(),cell.getValueOffset(),cell.getValueLength());
    			System.out.println("值:" + str4);
    			System.out.println("时间戳:" + cell.getTimestamp());
    		}
    	}
    	
    	//向已经创建好的表添加和删除指定的列簇或列
    	
    	//向表添加数据
    	public static void insterRow(String tableName,String rowKey,String colFamily,String col,String val) throws IOException {
    		init();
    		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();
    		close();
    	}
    	
    	//删除数据
    	public static void deleRow(String tableName,String rowKey,String colFamily,String col) throws IOException {
    		init();
    		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();
    		close();
    	}
    	
    	//清空指定的表的所有记录数据
    	public static void clearRows(String tableName) throws IOException {
    		init();
    		TableName tablename = TableName.valueOf(tableName);
    		admin.disableTable(tablename);
    		System.out.println("disable...delete...");
    		admin.deleteTable(tablename);
    		System.out.println("delete...over...create");
    		TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tablename);
    		ColumnFamilyDescriptor colFamilyDes=ColumnFamilyDescriptorBuilder.newBuilder(" ".getBytes()).build();
    		tableDescriptor.setColumnFamily(colFamilyDes).build();
    		admin.createTable(tableDescriptor.build());
    		
    		close();
    	}
    
    	//统计表的行数
    	public static void countRows(String tableName) throws IOException {
    		init();
    		Table table = connection.getTable(TableName.valueOf(tableName));
    		Scan scan = new Scan();
    		ResultScanner scanner = table.getScanner(scan);
    		int num = 0;
    		for (Result result = scanner.next();result!=null;result=scanner.next()) {
    			num++;
    		}
    		System.out.println("行数:" + num);
    		scanner.close();
    		close();
    	}
    	
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    //		listTables();
    //		getData("teacher");
    //		getData("student");
    //		deleRow("s1", "lisi", "score", "English");
    //		clearRows("s1");
    //		countRows("s2");
    		insterRow("s2", "xiaohong", "score", "Computer", "60");
    	}
    
    }

(二)HBase数据库操作

1. 现有以下关系型数据库中的表和数据(见表14-3到表14-5),要求将其转换为适合于HBase存储的表并插入数据:

表14-3 学生表(Student)

学号(S_No)

姓名(S_Name)

性别(S_Sex)

年龄(S_Age)

2015001

Zhangsan

male

23

2015002

Mary

female

22

2015003

Lisi

male

24

表14-4 课程表(Course)

课程号(C_No)

课程名(C_Name)

学分(C_Credit)

123001

Math

2.0

123002

Computer Science

5.0

123003

English

3.

表14-5 选课表(SC)

学号(SC_Sno)

课程号(SC_Cno)

成绩(SC_Score)

2015001

123001

86

2015001

123003

69

2015002

123002

77

2015002

123003

99

2015003

123001

98

2015003

123002

95

创建表:

 添加数据:

 

 

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指定的行的记录。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Test2 {
    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();
        }
    }
    /*createTable(String tableName, String[] fields)
	创建表,参数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("table is exists!");
            admin.disableTable(tablename);
            admin.deleteTable(tablename);//删除原来的表
            System.out.println("删除成功!");
        }

        System.out.println("开始创建表...");
        List<ColumnFamilyDescriptor> colFamilyList=new ArrayList<>();
        TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tablename);
        for(String str:fields) {
			ColumnFamilyDescriptor colFamilyDes=ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(str)).build();
			colFamilyList.add(colFamilyDes);
		}
		TableDescriptor tableDes=tableDescriptor.setColumnFamilies(colFamilyList).build();
		admin.createTable(tableDes);
        System.out.println(tableName+"创建成功!");
        close();
    }


    /*addRecord(String tableName, String row, String[] fields, String[] values)
	向表tableName、行row(用S_Name表示)和字符串数组files指定的单元格中添加对应的数据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));
        System.out.println("准备添加数据...");
        for(int i = 0;i != fields.length;i++){
            Put put = new Put(row.getBytes());
            String[] cols = fields[i].split(":");
            put.addColumn(cols[0].getBytes(),cols[1].getBytes(), values[i].getBytes());
            System.out.println(i+"put..."+i);
            table.put(put);
            System.out.println(i+"...ok");
        }
        table.close();
        
        close();
    }
    /*(3)scanColumn(String tableName, String column)
	浏览表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();
        scan.addFamily(Bytes.toBytes(column));
        ResultScanner scanner = table.getScanner(scan);
        for (Result result = scanner.next(); result != null; result = scanner.next()){
            showCell(result);
        }
        table.close();
        close();
    }
    //格式化输出
    public static void showCell(Result result){
        Cell[] cells = result.rawCells();
        for(Cell cell:cells){
            System.out.println("RowName:"+new String(Bytes.toString(cell.getRowArray(),cell.getRowOffset(), cell.getRowLength()))+" ");
            System.out.println("Timetamp:"+cell.getTimestamp()+" ");
            System.out.println("column Family:"+new String(Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(), cell.getFamilyLength()))+" ");
            System.out.println("row Name:"+new String(Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(), cell.getQualifierLength()))+" ");
            System.out.println("value:"+new String(Bytes.toString(cell.getValueArray(),cell.getValueOffset(), cell.getValueLength()))+" ");           
        }
    }
    /*modifyData(String tableName, String row, String column)
	修改表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 put = new Put(row.getBytes());
        String[] col = column.split(":");
        put.addColumn(col[0].getBytes(),col[1].getBytes(),val.getBytes());
        table.put(put);
        table.close();
        close();
    }
    /*(5)deleteRow(String tableName, String row)
	删除表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)throws IOException{
//      scanColumn("s1","score");
//    	String[] fields = {"score"};
//    	createTable("s1",fields);
    	String tableName = "s1";
    	String row = "001";
//    	String[] fields = {"score:Math", "score:Computer Science", "score:English"};
//    	String[] values = {"100","80","60"};
//    	addRecord(tableName,row,fields,values);
//    	scanColumn(tableName,"score");
//    	String column = "score:English";
//    	String val = "70";
//    	modifyData(tableName,row, column, val);
    	deleteRow(tableName,row);
  }
}
  • 36
    点赞
  • 230
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验三是熟悉常用hbase操作HBase是一个高可靠性、高性能、分布式的开源NoSQL数据库,它基于Hadoop分布式文件系统HDFS运行,并利用Hadoop的容错性和高可用性。 在这个实验中,我们需要掌握一些常用HBase操作,如创建表、插入数据、查询数据等。具体步骤如下: 首先,我们需要创建一个HBase表。可以使用create命令,在语句中指定表名和列族。列族是HBase中最小的存储单元,所有的数据都存储在列族中。 接下来,我们可以使用put命令向表中插入数据。插入数据需要指定表名、行键和列族及其对应的列名和值。行键是表中每一行的唯一标识,可以用来快速定位数据。 查询数据是HBase的一个重要功能。我们可以使用get命令查询指定行的数据,也可以使用scan命令扫描表中的所有行。查询时需要指定表名、行键和列族及其对应的列名。 除了查询数据,HBase还支持删除数据和删除表。删除数据可以使用delete命令,指定表名、行键和列族及其对应的列名。删除表可以使用disable和drop命令,先禁用表再删除表。 在实验中,我们还可以尝试使用HBase的其他功能,如增加列族、修改列族、修改表属性等。 总而言之,实验三通过熟悉HBase常用操作,帮助我们掌握HBase的基本使用方法。掌握了这些操作,我们就可以在实际应用中使用HBase来存储和查询大规模数据,提高数据处理效率和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值