跳转至

练习二:熟悉常用的 HBase 操作 - 编程实现

参考

  1. 厦门大学林子雨老师 - 大数据原理与应用 第四章 分布式数据库HBase 学习指南
  2. CSDN - 实验3 熟悉常用的HBase操作
  3. CSDN - 【小白视角】大数据基础实践(四) 分布式数据库HBase的常用操作

1 导入 HBase 相关的 Jar 包

将以下两大部分的 *.jar 文件导入到新建的 JAVA 工程项目中:

  • ~/usr/local/hbase/lib 目录下全部的 *.jar 文件
  • ~/usr/local/hbase/lib/client-facing-thirdparty 目录下全部的 *.jar 文件

导入所需的 JAVA 包

1
2
3
4
5
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;

2 HBase 数据库连接

2.1 建立连接

  每次对 HBase 数据库进行操作之前,都需要先连接数据库才能进行增删查改的操作。

  configuration.set() 的配置与 hbase-site.xml 紧密相关。

连接 HBase 数据库函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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();
    }
}

2.2 关闭连接

  在对 HBase 数据库操作结束后,最好是关闭连接以便下次其他操作的进行。

关闭连接函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public static void close(){
    try{
        if(admin != null){
            admin.close();
        }
        if(null != connection){
            connection.close();
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

3 数据库操作

3.1 创建表

  接下来我们将会把增删查改函数逐一封装实现,最终在 main() 主函数中调用。HBase 的表中会有一个系统默认的属性作为主键,主键无需自行创建,默认为 put 命令操作中表名后第一个数据,因此此处无需创建 id 列。

创建表函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 创建表
 * @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("table is exists!");
    }else {
        TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
        for(String str:colFamily){
            ColumnFamilyDescriptor family = 
                ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(str)).build();
            tableDescriptor.setColumnFamily(family);
        }
        admin.createTable(tableDescriptor.build());
    }
    close();
}

3.2 添加数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/**
 * 添加数据
 * @param tableName 表名
 * @param rowKey 行键
 * @param colFamily 列族
 * @param col 列限定符
 * @param val 数据
 * @throws IOException
 */
public static void insertData(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();
}

3.3 浏览数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/** 
 * 获取某单元格数据
 * @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);
    System.out.println(new String(result.getValue(colFamily.getBytes(),col==null?null:col.getBytes())));
    table.close();
    close();
}

3.4 查看 HBase 中所有表的信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/**
 * 查看已有表
 * @throws IOException
 */
public static void listTables() throws IOException {
    init();
    HTableDescriptor hTableDescriptors[] = admin.listTables();
    for(HTableDescriptor hTableDescriptor :hTableDescriptors){
        System.out.println(hTableDescriptor.getNameAsString());
    }
    close();
}

3.5 向指定的单元格添加数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/**
 * 向指定的单元格添加数据
 * @param tableName 表名
 * @param rowKey 行键
 * @param colFamily 列族
 * @param col 列限定符
 * @param val 数据
 * @throws IOException
 */
public static void addRecord(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();
}

3.6 查看指定列的数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
/** 
 * 查看指定列的数据
 * @param tableName 表名
 * @param col 列限定符
 * @throws IOException
 */
public static void scanColunm(String tableName, 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);
    System.out.println(new String(result.getValue(colFamily.getBytes(),col==null?null:col.getBytes())));
    table.close();
    close();
}

3.7 编辑某单元格的数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/**
 * 编辑某单元格的数据
 * @param tableName 表名
 * @param rowKey 行键
 * @param colFamily 列族
 * @param col 列限定符
 * @param val 数据
 * @throws IOException
 */
public static void modifyData(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();
}

3.8 删除指定行的数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 删除指定行的数据
 * @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();
}

全部代码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
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;

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("table 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))+" ");
        }
    }
}

最后更新: 2023-03-08
创建日期: 2022-12-27
作者: gis-xh