1. IDEA 连接 HBASE
1、idea
创建一个 maven
项目
2、添加相关依赖(HBASE
客户端(最主要)、服务端),pom.xml
:
<dependencies><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><version>1.2.6</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>1.2.6</version></dependency>
</dependencies>
3、在 resources
中添加 core-site.xml、hbase-site.xml
4、修改本机的 hosts
文件(在C:\Windows\System32\drivers\etc
下),添加集群的 IP
名称:
192.168.131.137 hadoop1
192.168.131.138 hadoop2
192.168.131.139 hadoop3
注意:此步骤不添加,有可能会导致
idea
执行不成功!
项目结构:
F:.
│ pom.xml
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─jun
│ │ │ └─test
│ │ │ TestApi.java
│ │ │
│ │ └─resources
│ │ core-site.xml
│ │ hbase-site.xml
│ │
│ └─test
│ └─java
└─target│ test_one.jar│├─classes│ │ core-site.xml│ │ hbase-site.xml│ ││ └─com│ └─jun│ └─test│ TestApi.class
参考文章:在本地用idea连接虚拟机上的hbase集群的实现代码
2. DDL 表操作
DDL
与表操作有关,比如:
- 判断表是否存在
- 创建、删除、修改表
- 创建命名空间
2.1 配置连接
package com.jun.test;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;import java.io.IOException;public class TestApi {public static Connection connection = null;public static Admin admin = null;static {try {// 获取配置信息Configuration configuration = HBaseConfiguration.create();configuration.set("hbase.zookeeper.quorum", "hadoop1,hadoop2,hadoop3");// 创建连接对象connection = ConnectionFactory.createConnection(configuration);// 创建 admin 对象admin = connection.getAdmin();} catch (IOException e) {e.printStackTrace();}}// 关闭连接public static void close() {if (admin != null) {try {admin.close();} catch (IOException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) throws IOException {// 判断表是否存在
// System.out.println(isTableExists("t1"));// 创建表
// createTable("t2", "info");// 将表创建到命名空间中
// createTable("0808:t2", "info");// 删除表
// deleteTable("t2");// 创建命名空间
// createNameSpace("0808");// 关闭资源close();}
}
2.2 判断表是否存在
// 判断表是否存在
public static boolean isTableExists(String tableName) throws IOException {boolean exists = admin.tableExists(TableName.valueOf(tableName));return exists;
}
2.3 创建表
创建表包括:添加列族信息、还可以将表添加到命名空间,创建之前可以先检查该表是否存在:
// 创建表
public static void createTable(String tableName, String... cfs) throws IOException {// 判断列族信息if (cfs.length <= 0) {System.out.println("请设置列族信息!!!");return;}// 判断表是否存在if (isTableExists(tableName)) {System.out.println(tableName + " 表已存在!!!");return;}// 创建表描述器对象HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(tableName));// 循环添加列族for (String cf : cfs) {descriptor.addFamily(new HColumnDescriptor(cf));}// 创建表admin.createTable(descriptor);System.out.println("表 " + tableName + " 创建成功!!!");
}
2.4 删除表
// 删除表
public static void deleteTable(String tableName) throws IOException {if (isTableExists(tableName)) {admin.disableTable(TableName.valueOf(tableName)); // 先停用表,再删除admin.deleteTable(TableName.valueOf(tableName));System.out.println("表 " + tableName + " 删除成功!!!");} else {System.out.println("表 " + tableName + " 不存在!!!");}
}
2.5 创建命名空间
// 创建命名空间
public static void createNameSpace(String ns) {// 创建命名空间描述器NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(ns).build();// 创建命名空间try {admin.createNamespace(namespaceDescriptor);System.out.println(ns + "命名空间创建成功!!!");} catch (NamespaceExistException e) {System.out.println("命名空间 " + ns + " 已存在!!!");}catch (IOException e) {e.printStackTrace();}}
可以在 hbase shell
中使用 list_namespace
查看命名空间:
hbase(main):012:0> list_namespace
NAMESPACE 0808 default hbase
3 row(s) in 0.0420 seconds// t2 表在 0808 命名空间里
hbase(main):014:0> list
TABLE 0808:t2 t1
2 row(s) in 0.0430 seconds=> ["0808:t2", "t1"]
3. DML 表记录操作
DML
主要是针对表的记录的操作,如插入、删除记录、查询记录等
3.1 插入数据
插入单条数据
// 插入数据
public static void putData(String tableName, String rowKey, String cf, String cn, String value) throws IOException {// 获取表对象Table table = connection.getTable(TableName.valueOf(tableName));// 获取 Put 对象Put put = new Put(Bytes.toBytes(rowKey));// 给 put 对象赋值put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cn), Bytes.toBytes(value));// 插入数据table.put(put);System.out.println("数据插入成功!!!");// 关闭表连接table.close();
}
测试:
// 插入数据
putData("t2", "10001", "info", "name", "rose");
插入多条数据
使用集合:
public static byte[] getBytes(String value) {return Bytes.toBytes(value);
}// 插入多条数据
public static void putManyData(String tableName, String cf, String cn, String value) throws IOException {Table table = connection.getTable(TableName.valueOf(tableName));// 定义一个集合List<Put> puts = new ArrayList<>();int row_key = 10001;for (int i = 1; i <= 5; i++) {row_key = row_key + i;Put put = new Put(getBytes(String.valueOf(row_key)));put.addColumn(getBytes(cf), getBytes(cn + i), getBytes(value + i));puts.add(put);}table.put(puts);System.out.println("成功插入多行数据!");table.close();
}
测试:
// 插入多条数据
putManyData("t2", "info", "alias", "jun");// scan t2
hbase(main):005:0> scan 't2'
ROW COLUMN+CELL
10001 column=info:name, timestamp=1628369721705, value=rose 10002 column=info:alias1, timestamp=1628383262854, value=jun1 10004 column=info:alias2, timestamp=1628383262854, value=jun2 10007 column=info:alias3, timestamp=1628383262854, value=jun3 10011 column=info:alias4, timestamp=1628383262854, value=jun4 10016 column=info:alias5, timestamp=1628383262854, value=jun5
6 row(s) in 0.0860 seconds
3.2 get 数据
获取某行数据
// get 单条数据
public static void getData(String tableName, String rowKey) throws IOException {Table table = connection.getTable(TableName.valueOf(tableName));Get get = new Get((Bytes.toBytes(rowKey)));// 获取最大版本数System.out.println(get.getMaxVersions());// System.out.println(get.setTimeStamp());// 获取整行数据Result result = table.get(get);for (Cell cell : result.rawCells()) {System.out.println("行键: " + Bytes.toString(result.getRow()));System.out.println("列族: " + Bytes.toString(CellUtil.cloneFamily(cell)));System.out.println("列: " + Bytes.toString(CellUtil.cloneQualifier(cell)));System.out.println("值: " + Bytes.toString(CellUtil.cloneValue(cell)));System.out.println("时间戳: " + cell.getTimestamp());}table.close();
}
测试数据:
// 获取数据
getData("t2", "10001");1
行键: 10001
列族: info
列: name
值: rose
时间戳: 1628369721705
指定列族、列名
// 指定列族
get.addFamily(Bytes.toBytes(cf));// 指定列名
get.addColumn(Bytes.toBytes(cn));
3.3 scan 数据
// scan 所有数据
public static void scanData(String tableName) throws IOException {Table table = connection.getTable(TableName.valueOf(tableName));Scan scan = new Scan();ResultScanner resultScanner = table.getScanner(scan);for (Result result : resultScanner) {Cell[] cells = result.rawCells();for (Cell cell : cells) {System.out.println("行键: " + Bytes.toString(result.getRow()));System.out.println("列族: " + Bytes.toString(CellUtil.cloneFamily(cell)));System.out.println("列: " + Bytes.toString(CellUtil.cloneQualifier(cell)));System.out.println("值: " + Bytes.toString(CellUtil.cloneValue(cell)));System.out.println("时间戳: " + cell.getTimestamp());System.out.println("-------------------------------------------\n\n");}}table.close();
}
测试数据:
// 扫描所有数据
scanData("t2");行键: 10001
列族: info
列: name
值: rose
时间戳: 1628369721705
-------------------------------------------行键: 10002
列族: info
列: alias1
值: jun1
时间戳: 1628383262854
-------------------------------------------行键: 10004
列族: info
列: alias2
值: jun2
时间戳: 1628383262854
-------------------------------------------行键: 10007
列族: info
列: alias3
值: jun3
时间戳: 1628383262854
-------------------------------------------行键: 10011
列族: info
列: alias4
值: jun4
时间戳: 1628383262854
-------------------------------------------行键: 10016
列族: info
列: alias5
值: jun5
时间戳: 1628383262854
-------------------------------------------
建议
使用 scan
扫描全表时,最好设置 startRow、endRow
,亦或者是带过滤条件的翻页,而非全表扫描:
// 设置 startRow
Scan(Bytes.toBytes("startRow"))// 设置 startRow、endRow
Scan(Bytes.toBytes("startRow"), Bytes.toBytes("endRow"))// 实际工作中一般不知道 endRow,而是带过滤条件的翻页
Scan(Bytes.toBytes("startRow"), Filter filter)ResultScanner resultScanner = table.getScanner(scan);
3.4 删除数据
删除单行数据
// 删除单行数据
public static void deleteData(String tableName, String rowKey) throws IOException {Table table = connection.getTable(TableName.valueOf(tableName));// 获取 delete 对象Delete delete = new Delete(Bytes.toBytes(rowKey));// 删除指定的列族、列名// delete.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cn));table.delete(delete);System.out.println(rowKey + " 删除成功!!!");table.close();
}
测试:
// 删除单行数据
deleteData("t2", "10001");hbase(main):007:0> scan 't2'
ROW COLUMN+CELL 10002 column=info:alias1, timestamp=1628383262854, value=jun1 10004 column=info:alias2, timestamp=1628383262854, value=jun2 10007 column=info:alias3, timestamp=1628383262854, value=jun3 10011 column=info:alias4, timestamp=1628383262854, value=jun4 10016 column=info:alias5, timestamp=1628383262854, value=jun5
5 row(s) in 0.1290 seconds
删除多行数据
// 删除多行数据
public static void deleteManyData(String tableName, String... rows) throws IOException {Table table = connection.getTable(TableName.valueOf(tableName));List<Delete> deletes = new ArrayList<>();for (String row : rows) {Delete delete = new Delete(Bytes.toBytes(row));deletes.add(delete);}table.delete(deletes);System.out.println("删除成功!!!");table.close();
}
测试:
// 删除多行数据
deleteManyData("t2", "10002", "10007");hbase(main):008:0> scan 't2'
ROW COLUMN+CELL 10004 column=info:alias2, timestamp=1628383262854, value=jun2 10011 column=info:alias4, timestamp=1628383262854, value=jun4 10016 column=info:alias5, timestamp=1628383262854, value=jun5
3 row(s) in 0.1140 seconds
4. 参考文章
- 第6章HBase API操作
- HBase Java API 批量操作
- hbase实战之javaAPI插入数据
- HBase- ddl(表操作)、dml(记录操作)的基本语法操作
- HBase学习之路 (六)过滤器