HBase分布式数据库操作与编程——HBase 练习、HBase Shell数据库表创建、HBase Shell数据访问操作、HBase Java API编程

HBase分布式数据库操作与编程目录

一、实验目的

1.掌握HBase操作常用Shell命令;
2.掌握HBase数据表的创建、添加数据、查看数据、删除数据、删除表、查询历史数据等操作;
3.掌握HBase APIs编程实践方法

二、实验内容

第1题 HBase 练习
【实验内容】
1.实现HBase的配置并完成http://dblab.xmu.edu.cn/blog/install-hbase/上的javac程序练习。
1、切换到/usr/local/hbase目录并编辑/.bashrc文件(在/.bashrc文件中export PATH这行追加/usr/local/hbase/bin)
在这里插入图片描述
2、编辑完成后,再执行source命令使上述配置在当前终端立即生效
在这里插入图片描述
3、添加HBase权限(将hbase下的所有文件的所有者改为hadoop,hadoop是当前用户的用户名)
在这里插入图片描述
4、 查看HBase版本,确定hbase安装成功(看到以下输出消息表示HBase已经安装成功)
在这里插入图片描述
5、用vi命令打开并编辑hbase-env.sh
在这里插入图片描述
配置JAVA环境变量如图,配置HBASE_MANAGES_ZK为true,表示由hbase自己管理zookeeper,不需要单独的zookeeper
在这里插入图片描述
6、打开并编辑hbase-site.xml
在这里插入图片描述
在启动HBase前需要设置属性hbase.rootdir,用于指定HBase数据的存储位置(以防每次重启系统都会丢失数据)
在这里插入图片描述
7、测试运行(首先切换目录至HBase安装目录/usr/local/hbase;再启动HBase)
在这里插入图片描述
8、打开shell命令行模式(用户可以通过输入shell命令操作HBase数据库)
在这里插入图片描述
9、退出shell命令行模式,停止HBase运行
在这里插入图片描述
10、配置/usr/local/hbase/conf/hbase-env.sh
在这里插入图片描述
配置JAVA_HOME,HBASE_CLASSPATH,HBASE_MANAGES_ZK.
HBASE_CLASSPATH设置为本机Hadoop安装目录下的conf目录(即/usr/local/hadoop/conf)
在这里插入图片描述
11、用命令vi打开并编辑hbase-site.xml
在这里插入图片描述
hbase.rootdir指定HBase的存储目录;hbase.cluster.distributed设置集群处于分布式模式
在这里插入图片描述
12、登陆ssh,切换目录至/usr/local/hadoop ,启动hadoop
在这里插入图片描述
13、命令jps(能看到NameNode,DataNode和SecondaryNameNode都已经成功启动,表示hadoop启动成功)
在这里插入图片描述
14、切换目录至/usr/local/hbase,启动HBase(输入命令jps,看到以下界面说明hbase启动成功)
在这里插入图片描述
15、进入shell界面
在这里插入图片描述
16、退出shell界面,停止HBase运行
在这里插入图片描述
编程实践
1、HBase中用create命令创建表
在这里插入图片描述
2、通过describe命令查看“student”表的基本信息
在这里插入图片描述
3、添加数据( 当运行命令:put ‘student’,’95001’,’Sname’,’LiYing’时,即为student表添加了学号为95001,名字为LiYing的一行数据,其行键为95001 )
在这里插入图片描述
4、为95001行下的course列族的math列添加了一个数据
在这里插入图片描述
5、为95001行下的course列族的Sage列添加了一个数据
在这里插入图片描述
6、为95001行下的course列族的Sdept列添加了一个数据
在这里插入图片描述
7、删除数据,删除了student表中95001行下的Ssex列的所有数据
在这里插入图片描述
8、get命令,(用于查看某一行数据,返回的是‘student’表‘95001’行的数据)
在这里插入图片描述
9、scan命令(用于查看某个表的全部数据)
在这里插入图片描述
10、删除student表中的95001行的全部数据
在这里插入图片描述
11、删除表有两步,第一步先让该表不可用,第二步删除表
在这里插入图片描述
12、在创建表的时候,指定保存的版本数(假设指定为5)
在这里插入图片描述
13、put命令,插入数据然后更新数据,使其产生历史版本数据
在这里插入图片描述
14、询时,指定查询的历史版本数。默认会查询出最新的数据。(有效取值为1到5)
在这里插入图片描述
15、Eclipse编写java程序,来对HBase数据库进行增删改查等操作
ExampleForHbase类代码如下

    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.*;
    import org.apache.hadoop.hbase.client.*;
    import java.io.IOException;
     
    public class ExampleForHbase{
        public static Configuration configuration;
        public static Connection connection;
        public static Admin admin;
     
        //主函数中的语句请逐句执行,只需删除其前的//即可,如:执行insertRow时请将其他语句注释
        public static void main(String[] args)throws IOException{
            //创建一个表,表名为Score,列族为sname,course
            createTable("Score",new String[]{"sname","course"});
     
            //在Score表中插入一条数据,其行键为95001,sname为Mary(因为sname列族下没有子列所以第四个参数为空)
            //等价命令:put 'Score','95001','sname','Mary'
            insertRow("Score", "95001", "sname", "", "Mary");
            //在Score表中插入一条数据,其行键为95001,course:Math为88(course为列族,Math为course下的子列)
            //等价命令:put 'Score','95001','score:Math','88'
            //insertRow("Score", "95001", "course", "Math", "88");
            //在Score表中插入一条数据,其行键为95001,course:English为85(course为列族,English为course下的子列)
            //等价命令:put 'Score','95001','score:English','85'
            //insertRow("Score", "95001", "course", "English", "85");
     
            //1、删除Score表中指定列数据,其行键为95001,列族为course,列为Math
            //执行这句代码前请deleteRow方法的定义中,将删除指定列数据的代码取消注释注释,将删除制定列族的代码注释
            //等价命令:delete 'Score','95001','score:Math'
            //deleteRow("Score", "95001", "course", "Math");
     
            //2、删除Score表中指定列族数据,其行键为95001,列族为course(95001的Math和English的值都会被删除)
            //执行这句代码前请deleteRow方法的定义中,将删除指定列数据的代码注释,将删除制定列族的代码取消注释
            //等价命令:delete 'Score','95001','score'
            //deleteRow("Score", "95001", "course", "");
     
            //3、删除Score表中指定行数据,其行键为95001
            //执行这句代码前请deleteRow方法的定义中,将删除指定列数据的代码注释,以及将删除制定列族的代码注释
            //等价命令:deleteall 'Score','95001'
            //deleteRow("Score", "95001", "", "");
     
            //查询Score表中,行键为95001,列族为course,列为Math的值
            //getData("Score", "95001", "course", "Math");
            //查询Score表中,行键为95001,列族为sname的值(因为sname列族下没有子列所以第四个参数为空)
            //getData("Score", "95001", "sname", "");
     
            //删除Score表
            //deleteTable("Score");
        }
     
        //建立连接
        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();
            }
        }
     
        /**
         * 建表。HBase的表中会有一个系统默认的属性作为主键,主键无需自行创建,默认为put命令操作中表名后第一个数据,因此此处无需创建id列
         * @param myTableName 表名
         * @param colFamily 列族名
         * @throws IOException
         */
        public static void createTable(String myTableName,String[] colFamily) throws IOException {
     
            init();
            TableName tableName = TableName.valueOf(myTableName);
     
            if(admin.tableExists(tableName)){
                System.out.println("talbe is exists!");
            }else {
                HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
                for(String str:colFamily){
                    HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
                    hTableDescriptor.addFamily(hColumnDescriptor);
                }
                admin.createTable(hTableDescriptor);
                System.out.println("create table success");
            }
            close();
        }
        /**
         * 删除指定表
         * @param tableName 表名
         * @throws IOException
         */
        public static void deleteTable(String tableName) throws IOException {
            init();
            TableName tn = TableName.valueOf(tableName);
            if (admin.tableExists(tn)) {
                admin.disableTable(tn);
                admin.deleteTable(tn);
            }
            close();
        }
     
        /**
         * 查看已有表
         * @throws IOException
         */
        public static void listTables() throws IOException {
            init();
            HTableDescriptor hTableDescriptors[] = admin.listTables();
            for(HTableDescriptor hTableDescriptor :hTableDescriptors){
                System.out.println(hTableDescriptor.getNameAsString());
            }
            close();
        }
        /**
         * 向某一行的某一列插入数据
         * @param tableName 表名
         * @param rowKey 行键
         * @param colFamily 列族名
         * @param col 列名(如果其列族下没有子列,此参数可为空)
         * @param val 值
         * @throws IOException
         */
        public static void insertRow(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();
        }
     
        /**
         * 删除数据
         * @param tableName 表名
         * @param rowKey 行键
         * @param colFamily 列族名
         * @param col 列名
         * @throws IOException
         */
        public static void deleteRow(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(colFamily.getBytes());
            //删除指定列的数据
            //delete.addColumn(colFamily.getBytes(), col.getBytes());
     
            table.delete(delete);
            table.close();
            close();
        }
        /**
         * 根据行键rowkey查找数据
         * @param tableName 表名
         * @param rowKey 行键
         * @param colFamily 列族名
         * @param col 列名
         * @throws IOException
         */
        public static void getData(String tableName,String rowKey,String colFamily,String col)throws  IOException{
            init();
            Table table = connection.getTable(TableName.valueOf(tableName));
            Get get = new Get(rowKey.getBytes());
            get.addColumn(colFamily.getBytes(),col.getBytes());
            Result result = table.get(get);
            showCell(result);
            table.close();
            close();
        }
        /**
         * 格式化输出
         * @param result
         */
        public static void showCell(Result result){
            Cell[] cells = result.rawCells();
            for(Cell cell:cells){
                System.out.println("RowName:"+new String(CellUtil.cloneRow(cell))+" ");
                System.out.println("Timetamp:"+cell.getTimestamp()+" ");
                System.out.println("column Family:"+new String(CellUtil.cloneFamily(cell))+" ");
                System.out.println("row Name:"+new String(CellUtil.cloneQualifier(cell))+" ");
                System.out.println("value:"+new String(CellUtil.cloneValue(cell))+" ");
            }
        }
    }

编程实例代码运行结果
在这里插入图片描述
执行完插入数据后,在shell界面中执行scan ‘Score’
在这里插入图片描述
第2题. HBase Shell数据库表创建
【实验内容】
根据以下关系型数据库表,使用HBase Shell设计并创建适宜的HBase数据表。
在这里插入图片描述
1、启动hadoop、hbase
在这里插入图片描述
2、进入hbase的shell界面
在这里插入图片描述
3、创建表格“Student”
在这里插入图片描述
4、创建表格“Score”和“SC”
在这里插入图片描述
5、查看已有的表格
在这里插入图片描述
6、给“Student”表学号为“2020001”添加姓名、性别、年龄
在这里插入图片描述
7、给“Student”表学号为“2020003”添加姓名、性别、年龄
在这里插入图片描述
8、给“Student”表学号为“2020005”添加姓名、性别、年龄
在这里插入图片描述
9、scan命令查看“Student”表格信息
在这里插入图片描述
10、给“Course”表学号为“123001、123002、123003”分别添加对应的课程名称
在这里插入图片描述
11、给“Course”表学号为“123001、123002、123003”添加学分
在这里插入图片描述
12、查看“Course”表格的全部数据
在这里插入图片描述
13、向学生表添加课程列族
在这里插入图片描述
14、scan命令查看“Student”表格信息
在这里插入图片描述
第3题 HBase Shell数据访问操作
【实验内容】
(1)使用HBase Shell命令向第1题所构建的HBase数据表中添加适宜数据;
(2)使用HBase Shell命令从第1题所构建的HBase数据表中查询出数据;
(3)使用HBase Shell命令从第1题所构建的HBase数据表中删除任一数据;
(4)使用HBase Shell命令统计第1题所构建的HBase数据表的行数。

【实验过程】(步骤、记录、数据、程序等)
请提供相应Shell操作命令或相应Shell界面截图证明。
1、在“Student”添加数据
在这里插入图片描述
2、查询出数据
在这里插入图片描述
3、删除任一数据
在这里插入图片描述
4、统计“Student”表的行数
在这里插入图片描述
第4题 HBase Java API编程
【实验内容】
根据第1,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表示)和字符串数组files指定的单元格中添加对应的数据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指定的行的记录。

1、创建java工程
在这里插入图片描述
2、菜单函数,java程序代码如下
HBaseModifyStudent类代码如下

import java.io.IOException;
import java.util.Scanner;
public class HBaseModifyStudent {
	public static void main(String[] args) throws IOException{
		HBaseStudentOperation h1=new HBaseStudentOperation();
		@SuppressWarnings("resource")
		Scanner in = new Scanner(System.in);
		while(true){
			System.out.println("**********************基于JAVA的Hbase数据库表及表的基本操作**********************");
			System.out.println("1、创建学生选课表");
			System.out.println("2、向创建的表中添加学生信息");
			System.out.println("3、浏览创建的选课表中指定列的数据");
			System.out.println("4、修改指定单元格的数据");
			System.out.println("5、删除指定行的数据");
			System.out.println("0、退出!");
			System.out.print("请输入你的选择:");
			int a=in.nextInt();
			switch(a){
			case 1: h1.createTable("StudentScore",new String[]{"student","Math","ComputerScience","English"});break;
			case 2: h1.addRecord("StudentScore","Zhangsan",new String[]{"student:S_No","student:S_Name","student:S_Sex","student:S_Age","Math:C_No","Math:C_Name","Math:C_Credit","Math:SC_Score","English:C_No","English:C_Name","English:C_Credit","English:SC_Score"}, new String[]{"2020001","Zhangsan","male","23","123001","Math","2.0","86","123003","English","3.0","69"});break;
			case 3: h1.scanColumn("StudentScore", "Math");break;
			case 4: h1.modifyData("StudentScore","Zhangsan","Math:SC_Score","89");break;
			case 5: h1.deleteRow("StudentScore","Zhangsan");break;
			case 0: return;
			}
		}
	}
}

在这里插入图片描述
3、连接和关闭Hbase数据库的JAVA代码
HBaseStudentOperation类代码如下

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.Scanner;
public class HBaseStudentOperation{
        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();
            }
        }
     
        /**
         * 建表。HBase的表中会有一个系统默认的属性作为主键,主键无需自行创建,默认为put命令操作中表名后第一个数据,因此此处无需创建id列
         * @param myTableName 表名
         * @param colFamily 列族名
         * @throws IOException
         */
        public static void createTable(String myTableName,String[] colFamily) throws IOException {
        	@SuppressWarnings("resource")
    		Scanner in = new Scanner(System.in);
            init();
            TableName tableName = TableName.valueOf(myTableName);
            if(admin.tableExists(tableName)){
                System.out.println("该表已经存在!");
                System.out.println("是否删除该表重新创建?");
                System.out.println("1、是");
                System.out.println("2、否");
                System.out.print("请输入你的选择:");
                int a=in.nextInt();
                switch(a){
                case 1:if (admin.tableExists(tableName)) {
                    		admin.disableTable(tableName);
                    		admin.deleteTable(tableName);
                    		System.out.println("表:"+tableName+"已成功删除");
                		}
                	   HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
                	   for(String str:colFamily){
                		  HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
                		  hTableDescriptor.addFamily(hColumnDescriptor);
                	    }
                	   admin.createTable(hTableDescriptor);
                	   System.out.println("表创建成功!");break;
                case 2:break;
                }
            }else {
                HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
                for(String str:colFamily){
                    HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
                    hTableDescriptor.addFamily(hColumnDescriptor);
                }
                admin.createTable(hTableDescriptor);
                System.out.println("表创建成功!");
            }
            close();
        }
        public void addRecord(String tableName,String rowKey,String []fields,String [] values) throws IOException {
            init();
            Table table = connection.getTable(TableName.valueOf(tableName));
            for (int i = 0; i < fields.length; i++) {
             Put put = new Put(rowKey.getBytes());
             String [] cols = fields[i].split(":");
             if(cols.length==1){
            	 put.addColumn(cols[0].getBytes(), "".getBytes(), values[i].getBytes());//因为当输入的是单列族,split仅读出一个字符字符串,即cols仅有一个元素
             }
             else {
            	 put.addColumn(cols[0].getBytes(), cols[1].getBytes(), values[i].getBytes());
            }
             table.put(put);
            }
            System.out.println("数据插入成功");
            table.close();
            close();
           }
        public 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.next(); result !=null;result = scanner.next()) {
        		showCell(result);
        		}
        	table.close();
        	close();
        	}
        public void modifyData(String tableName,String rowKey,String column,String value) throws IOException{
        	init();
        	Table table = connection.getTable(TableName.valueOf(tableName));
        	Put put = new Put(rowKey.getBytes());
        	String [] cols = column.split(":");
        	if(cols.length==1){
        		put.addColumn(column.getBytes(),"".getBytes() , value.getBytes());//qualifier:列族下的列名
        	}
        	else { 
        		put.addColumn(cols[0].getBytes(),cols[1].getBytes() , value.getBytes());//qualifier:列族下的列名
        	}
        	System.out.println("信息修改成功!");
        	table.put(put);
        	table.close();
        	close();
       }
       public void showCell(Result result){
            Cell[] cells = result.rawCells();
            for(Cell cell:cells){
                System.out.println("RowName:"+new String(CellUtil.cloneRow(cell))+" ");
                System.out.println("Timetamp:"+cell.getTimestamp()+" ");
                System.out.println("column Family:"+new String(CellUtil.cloneFamily(cell))+" ");
                System.out.println("row Name:"+new String(CellUtil.cloneQualifier(cell))+" ");
                System.out.println("value:"+new String(CellUtil.cloneValue(cell))+" ");
            }
        }
       public void deleteRow(String tableName,String rowKey) throws IOException{
       	init();
       	Table table = connection.getTable(TableName.valueOf(tableName));
       	Delete delete = new Delete(rowKey.getBytes());
       	table.delete(delete);
       	System.out.println("删除成功!");
       	table.close();
       	close();
       }
    }

在这里插入图片描述
在这里插入图片描述
4、创建学生信息表
在这里插入图片描述
在这里插入图片描述
5、添加学生选课信息
在这里插入图片描述
6、浏览学生选课信息表
在这里插入图片描述
7、修改学生选课信息
在这里插入图片描述
在这里插入图片描述
8、删除学生选课信息
在这里插入图片描述
运行结果如下
选择1,创建学生选课表
在这里插入图片描述
再次创建,提示该表已经存在
在这里插入图片描述
选择2,学生Zhangsan选课信息的录入
在这里插入图片描述
Scan命令,查看插入成功的结果
在这里插入图片描述
选择3,进行学生Zhangsan数学课程信息的查询,结果如下
在这里插入图片描述
选择4,进行学生Zhangsan数学成绩的修改
在这里插入图片描述
Scan命令查询结果(之前是86分,现在89分)
在这里插入图片描述
选择5,进行学生Zhangsan一行的信息的删除
在这里插入图片描述
Scan命令查询结果(可见,zhangshan的信息已经被全部删除)
在这里插入图片描述
做到这里,本次HBase分布式数据库操作与编程基本完成,过程截图不清楚或有问题的可以给我评论或私信,命令行代码希望自己敲,可以加深理解,加油!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44830040/article/details/105988358