如何使用Java连接HBase数据库
Java
连接HBase
需要两个类:
HBaseConfiguration
ConnectionFactory
HBaseConfiguration
要连接HBase
我们首先需要创建Configuration
对象,这个对象我们需要通过HBaseConfiguration
(HBase
配置)对象来进行创建,HBaseConfiguration
看名字我们就能猜到它的用途:读取指定路径下hbase-site.xml
和hbase-default.xml
的配置信息。
具体用法:
- Configuration config = HBaseConfiguration.create(); //使用create()静态方法就可以得到Configuration对象
ConnectionFactory
获取到连接对象Connextion
我们就算连接上了HBase
了,怎么获取呢?
通过ConnectionFactory
(连接工厂)的方法我们就能获取到Connection
(连接对象)了。
具体用法:
- Connection connection = ConnectionFactory.createConnection(config); //config为前文的配置对象
使用这两个步骤就能完成连接HBase
了。
注意:在1.0之前的版本HBase
是使用HBaseAdmin
和HTable
等来操作HBase
的,但是在1.0
之后的版本中这些被弃用了,新的客户端API
更加干净简洁,本文使用的HBase
是2.1.1
版本(18年10月发布)的,
创建表
要创建表我们需要首先创建一个Admin
对象,然后让它来创建一张表:
- Admin admin = connection.getAdmin(); //使用连接对象获取Admin对象
- TableName tableName = TableName.valueOf("test");//定义表名
- HTableDescriptor htd = new HTableDescriptor(tableName);//定义表对象
- HColumnDescriptor hcd = new HColumnDescriptor("data");//定义列族对象
- htd.addFamily(hcd); //添加
- admin.createTable(htd);//创建表
HBase2.X创建表
上述创建表的方法是HBase1.X
版本的方式,而在HBase2.X
的版本中创建表使用了新的API
,创建表关键代码如下:
- TableName tableName = TableName.valueOf("test");//定义表名
- //TableDescriptor对象通过TableDescriptorBuilder构建;
- TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
- ColumnFamilyDescriptor family = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data")).build();//构建列族对象
- tableDescriptor.setColumnFamily(family);//设置列族
- admin.createTable(tableDescriptor.build());//创建表
在2.X
版本中主要是HTableDescriptor
对象被弃用,取而代之的是TableDescriptor
对象,TableDescriptor
对象通过TableDescriptorBuilder
构建;
- TableName tableName = TableName.valueOf("test");
- TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
然后添加列簇方法变更:
- ColumnFamilyDescriptor family = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data")).build();//构建列族对象
- tableDescriptor.setColumnFamily(family); //设置列族
最后由Admin
对象进行创建表操作:
- admin.createTable(tableDescriptor.build());
值得咱们注意的是,如果你的HBase
环境是1.X
的那么你只能使用第一种方式来创建表,如果是2.X
的版本,那么两种方式你都可以使用(本实训使用的 HBase
是2.1.1
版本,所以两种都可用)
HBase创建表示例
请你编写一个Java
程序,在HBase
中创建表dept
,emp
,列都为:data
。
- package step1;
- import java.io.IOException;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.hbase.HBaseConfiguration;
- import org.apache.hadoop.hbase.HColumnDescriptor;
- import org.apache.hadoop.hbase.HTableDescriptor;
- import org.apache.hadoop.hbase.TableName;
- import org.apache.hadoop.hbase.client.Admin;
- import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
- import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
- import org.apache.hadoop.hbase.client.Connection;
- import org.apache.hadoop.hbase.client.ConnectionFactory;
- import org.apache.hadoop.hbase.client.Get;
- import org.apache.hadoop.hbase.client.Put;
- import org.apache.hadoop.hbase.client.Result;
- import org.apache.hadoop.hbase.client.ResultScanner;
- import org.apache.hadoop.hbase.client.Scan;
- import org.apache.hadoop.hbase.client.Table;
- import org.apache.hadoop.hbase.client.TableDescriptor;
- import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
- import org.apache.hadoop.hbase.util.Bytes;
- public class Task{
- public void createTable()throws Exception{
- /********* Begin *********/
- Configuration config = HBaseConfiguration.create(); //使用create()静态方法就可以得到Configuration对象
- Connection connection = ConnectionFactory.createConnection(config); //config为前文的配置对象
- try{
- Admin admin = connection.getAdmin();
- try{
- TableName tableName = TableName.valueOf("dept");
- TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
- ColumnFamilyDescriptor family = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data")).build();
- tableDescriptor.setColumnFamily(family);
- admin.createTable(tableDescriptor.build());
- TableName emp = TableName.valueOf("emp");
- TableDescriptorBuilder emptableDescriptor = TableDescriptorBuilder.newBuilder(emp);
- ColumnFamilyDescriptor empfamily = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data")).build();
- emptableDescriptor.setColumnFamily(empfamily);
- admin.createTable(emptableDescriptor.build());
- }finally{
- admin.close();
- }
- }finally{
- connection.close();
- }
- /********* End *********/
- }
- }
添加数据
要对一个表添加数据,我们需要一个Put
对象,在定义Put
对象之前我们需要获取到Table
对象,这样才能对指定的表进行操作:
- Table table = connection.getTable(tableName);//获取Table对象
- try {
- byte[] row = Bytes.toBytes("row1"); //定义行
- Put put = new Put(row); //创建Put对象
- byte[] columnFamily = Bytes.toBytes("data"); //列簇
- byte[] qualifier = Bytes.toBytes(String.valueOf(1)); //列
- byte[] value = Bytes.toBytes("张三丰"); //值
- put.addColumn(columnFamily, qualifier, value);
- table.put(put); //向表中添加数据
- } finally {
- //使用完了要释放资源
- table.close();
- }
添加数据示例:
- package step2;
- import java.io.IOException;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.hbase.HBaseConfiguration;
- import org.apache.hadoop.hbase.HColumnDescriptor;
- import org.apache.hadoop.hbase.HTableDescriptor;
- import org.apache.hadoop.hbase.TableName;
- import org.apache.hadoop.hbase.client.Admin;
- import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
- import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
- import org.apache.hadoop.hbase.client.Connection;
- import org.apache.hadoop.hbase.client.ConnectionFactory;
- import org.apache.hadoop.hbase.client.Get;
- import org.apache.hadoop.hbase.client.Put;
- import org.apache.hadoop.hbase.client.Result;
- import org.apache.hadoop.hbase.client.ResultScanner;
- import org.apache.hadoop.hbase.client.Scan;
- import org.apache.hadoop.hbase.client.Table;
- import org.apache.hadoop.hbase.client.TableDescriptor;
- import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
- import org.apache.hadoop.hbase.util.Bytes;
- public class Task {
- public void insertInfo()throws Exception{
- /********* Begin *********/
- Configuration config = HBaseConfiguration.create();
- Connection connection = ConnectionFactory.createConnection(config);
- Admin admin = connection.getAdmin();
- TableName tableName = TableName.valueOf("tb_step2"); //定义表名
- TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
- ColumnFamilyDescriptor family = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data")).build();// 构建列族对象
- tableDescriptor.setColumnFamily(family); // 设置列族
- admin.createTable(tableDescriptor.build()); // 创建表
- Table table = connection.getTable(tableName);//获取Table对象
- // 添加数据
- try{
- byte[] row1 = Bytes.toBytes("row1");
- Put put1 = new Put(row1);
- byte[] columnFamily1 = Bytes.toBytes("data"); // 列
- byte[] qualifier1 = Bytes.toBytes(String.valueOf(1)); // 列族修饰词
- byte[] value1 = Bytes.toBytes("张三丰"); // 值
- put1.addColumn(columnFamily1, qualifier1, value1);
- table.put(put1);
- byte[] row2 = Bytes.toBytes("row2");
- Put put2 = new Put(row2);
- byte[] columnFamily2 = Bytes.toBytes("data"); // 列
- byte[] qualifier2 = Bytes.toBytes(String.valueOf(2)); // 列族修饰词
- byte[] value2 = Bytes.toBytes("张无忌"); // 值
- put2.addColumn(columnFamily2, qualifier2, value2);
- table.put(put2);
- }finally {
- //使用完了要释放资源
- table.close();
- }
- /********* End *********/
- }
- }
获取指定行的数据
我们使用Get
对象与Table
对象就可以获取到表中的数据了。
- //获取数据
- Get get = new Get(Bytes.toBytes("row1")); //定义get对象
- Result result = table.get(get); //通过table对象获取数据
- System.out.println("Result: " + result);
- //很多时候我们只需要获取“值” 这里表示获取 data:1 列族的值
- byte[] valueBytes = result.getValue(Bytes.toBytes("data"), Bytes.toBytes("1")); //获取到的是字节数组
- //将字节转成字符串
- String valueStr = new String(valueBytes,"utf-8");
- System.out.println("value:" + valueStr);
上述代码就可以查到table
对象中行row1
的数据了,亲自试试验证一下结果吧。
扫描表中的数据
只获取一行数据显然不能满足我们全部的需求,我们想要获取表中所有的数据应该怎么操作呢?
Scan
、ResultScanner
对象就派上用场了,接下来我们看个示例你应该就明白这两个对象的用法了:
- Scan scan = new Scan();
- ResultScanner scanner = table.getScanner(scan);
- try {
- for (Result scannerResult: scanner) {
- System.out.println("Scan: " + scannerResult);
- byte[] row = scannerResult.getRow();
- System.out.println("rowName:" + new String(row,"utf-8"));
- }
- } finally {
- scanner.close();
- }
编程要求
使用本关知识,在右侧编辑器begin-end
处补充代码,输出t_step3
表中行号为row1
,列族为data:1
的值(以utf-8
编码),输出table_step3
表中所有行的行名称(因为直接输出scannerResult
会带有时间戳,所以输出行名方便测评)。
- import java.io.IOException;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.hbase.HBaseConfiguration;
- import org.apache.hadoop.hbase.HColumnDescriptor;
- import org.apache.hadoop.hbase.HTableDescriptor;
- import org.apache.hadoop.hbase.TableName;
- import org.apache.hadoop.hbase.client.Admin;
- import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
- import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
- import org.apache.hadoop.hbase.client.Connection;
- import org.apache.hadoop.hbase.client.ConnectionFactory;
- import org.apache.hadoop.hbase.client.Get;
- import org.apache.hadoop.hbase.client.Put;
- import org.apache.hadoop.hbase.client.Result;
- import org.apache.hadoop.hbase.client.ResultScanner;
- import org.apache.hadoop.hbase.client.Scan;
- import org.apache.hadoop.hbase.client.Table;
- import org.apache.hadoop.hbase.client.TableDescriptor;
- import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
- import org.apache.hadoop.hbase.util.Bytes;
- public class Task {
- public void queryTableInfo()throws Exception{
- /********* Begin *********/
- try{
- //连接HBase
- Configuration config = HBaseConfiguration.create();
- Connection connection = ConnectionFactory.createConnection(config);//config为前文的配置对象
- Admin admin = connection.getAdmin();//使用连接对象获取Admin对象
- //获取表
- TableName tableName = TableName.valueOf("tb_step2"); //定义表名
- Table table = connection.getTable(tableName);//获取Table对象
- //获取数据
- Get get = new Get(Bytes.toBytes("row1")); //定义get对象
- Result result = table.get(get); //通过table对象获取数据
- System.out.println("Result: " + result);
- //很多时候我们只需要获取“值” 这里表示获取 data:1 列族的值
- byte[] valueBytes = result.getValue(Bytes.toBytes("data"), Bytes.toBytes("1")); //获取到的是字节数组
- //将字节转成字符串
- String valueStr = new String(valueBytes,"utf-8");
- System.out.println("value:" + valueStr);
- Table step3Table = connection.getTable(tableStep3Name);
- //批量查询
- Scan scan = new Scan();
- ResultScanner scanner = table.getScanner(scan);
- try {
- for (Result scannerResult: scanner) {
- System.out.println("Scan: " + scannerResult);
- byte[] row = scannerResult.getRow();
- System.out.println("rowName:" + new String(row,"utf-8"));
- }
- } finally {
- scanner.close();
- }
- }finally{
- table.close();
- }
- /********* End *********/
- }
- }
- //连接HBase
- Configuration config = HBaseConfiguration.create();
- Connection connection = ConnectionFactory.createConnection(config);//config为前文的配置对象
- Admin admin = connection.getAdmin();//使用连接对象获取Admin对象
- //获取表
- TableName tableName = TableName.valueOf("t_step3"); //定义表名
- Table table = connection.getTable(tableName);//获取Table对象
- //获取数据
- Get get = new Get(Bytes.toBytes("row1")); //定义get对象
- Result result = table.get(get); //通过table对象获取数据
- System.out.println("Result: " + result);
- //很多时候我们只需要获取“值” 这里表示获取 data:1 列族的值
- byte[] valueBytes = result.getValue(Bytes.toBytes("data"), Bytes.toBytes("1")); //获取到的是字节数组
- //将字节转成字符串
- String valueStr = new String(valueBytes,"utf-8");
- System.out.println("value:" + valueStr);
- TableName tableStep3Name = TableName.valueOf("table_step3");
- Table step3Table = connection.getTable(tableStep3Name);
- //批量查询
- Scan scan = new Scan();
- ResultScanner scanner = table.getScanner(scan);
- try {
- for (Result scannerResult: scanner) {
- System.out.println("Scan: " + scannerResult);
- byte[] row = scannerResult.getRow();
- System.out.println("rowName:" + new String(row,"utf-8"));
- }
- } finally {
- scanner.close();
- }
- }finally{
- ;
- }
- /********* End *********/