IDEA代碼操作Hbase
1、操作Hbase的基本流程
package com.shujia;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import java.io.IOException;
public class Demo1TestAPI {
public static void main(String[] args) throws IOException {
//1、創建配置文件,設置HBase的連接地址(ZK的地址)
Configuration conf = HBaseConfiguration.create();
//第1個參數在 /usr/local/soft/hbase-1.4.6/conf/hbase-site.xml 中
//第2個參數需要我們自己指定
conf.set("hbase.zookeeper.quorum","master:2181,note01:2181,note2:2181");
//2、建立連接
Connection conn = ConnectionFactory.createConnection(conf);
//3、執行操作
//(1)對表的結構進行操作----getAdmin
Admin admin = conn.getAdmin();
//(2)對表的數據進行操作----getTable()
//參數需要傳入TableName類型,需要轉一下類型,不能直接傳入String類型
Table test = conn.getTable(TableName.valueOf("test"));
//4、關閉連接
conn.close();
}
}
2、程序案例---建表、查看、刪除、加載、獲取
package com.shujia;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class Demo2API {
Connection conn;
@Before
public void init() throws IOException {
//1、創建配置文件,設置HBase的連接地址(ZK的地址)
Configuration conf = HBaseConfiguration.create();
//第1個參數在 hbase-1.4.6/conf/hbase-site.xml 中,第2個參數需要我們自己指定
conf.set("hbase.zookeeper.quorum", "master:2181,note01:2181,note2:2181");
//2、建立連接(參數為配置對象的變量)
conn = ConnectionFactory.createConnection(conf);
}
@Test
//建表
public void createTable() throws IOException {
//對表的結構進行操作----getAdmin
Admin admin = conn.getAdmin();
//創建表結構
HTableDescriptor testAPI = new HTableDescriptor(TableName.valueOf("testAPI"));//new一個'表結構'對象,參數為'表名'
//創建列簇
HColumnDescriptor cf1 = new HColumnDescriptor("cf1");//new一個‘列簇的屬性’對象,參數為'列簇名'
cf1.setMaxVersions(3);//設置版本號
//給表testAPI添加列簇
testAPI.addFamily(cf1);
//創建表
admin.createTable(testAPI);
}
@Test
//查看表----list
public void listTables() throws IOException {
//對表的結構進行操作----getAdmin
Admin admin = conn.getAdmin();
//獲取表名
TableName[] tableNames = admin.listTableNames();
//遍歷表名
for (TableName tableName : tableNames) {
//TableName[]類型需要轉換為String類型
System.out.println(tableName.getNameAsString());//test test1 testAPI
}
}
@Test
//查看表結構----desc
public void descTableDescriptor() throws IOException {
//對表的結構進行操作----getAdmin
Admin admin = conn.getAdmin();
//將表名String類型轉化為TableName類型(因為在下面獲取表結構的時候需要傳入TableName類型)
TableName testAPI = TableName.valueOf("testAPI");
//獲取表結構
HTableDescriptor testAPIDesc = admin.getTableDescriptor(testAPI);
//獲取表結構中的列簇
HColumnDescriptor[] cfs = testAPIDesc.getColumnFamilies();
//遍歷列簇
for (HColumnDescriptor cf : cfs) {
System.out.println(cf.getNameAsString());//獲取列簇名 cf1
System.out.println(cf.getMaxVersions());//獲取版本號 3
System.out.println(cf.getTimeToLive());//獲取時間戳 2147483647
}
}
@Test
// 修改表結構----alter
// 對testAPI 將cf1的版本設置為5,並且新加一個列簇cf2
public void AlterTable() throws IOException {
//對表的結構進行操作----getAdmin
Admin admin = conn.getAdmin();
//將表名String類型轉化為TableName類型(因為在下面獲取表結構的時候需要傳入TableName類型)
TableName testAPI = TableName.valueOf("testAPI");
//獲取表結構
HTableDescriptor testAPIAlter = admin.getTableDescriptor(testAPI);
//獲取表結構中的列簇
HColumnDescriptor[] cfs = testAPIAlter.getColumnFamilies();
//遍歷列簇
for (HColumnDescriptor cf : cfs) {
//提取列簇名等於cf1的列簇(列簇需要轉化為String類型)
if ("cf1".equals(cf.getNameAsString())) {
cf.setMaxVersions(5);//將cf1的版本設置為5
}
}
//調用addFamily()方法添加新的列簇,參數需要傳入HColumnDescriptor類型
testAPIAlter.addFamily(new HColumnDescriptor("cf2"));
//調取修改方法,傳入參數,進行修改
admin.modifyTable(testAPI, testAPIAlter);
}
@Test
// drop
public void DropTable() throws IOException {
//對表的結構進行操作----getAdmin
Admin admin = conn.getAdmin();
//String類型轉化為TableName類型
TableName tableName = TableName.valueOf("test1");
//刪出表之前判斷一下表是否存在
if (admin.tableExists(tableName)) {
admin.disableTable(tableName); //表在刪除之前需要先禁用表--disable
admin.deleteTable(tableName); //刪除表
} else {
System.out.println("表不存在!");
}
}
@Test
// put
public void PutData() throws IOException {
//獲取想要插入數據的表,參數需要傳入TableName類型
//將表名String類型轉化為TableName類型
Table testAPI = conn.getTable(TableName.valueOf("testAPI"));
//創建Put對象,參數要求傳入一個rk的字節類型,需要轉型
Put put = new Put("001".getBytes());
//插入數據,需要傳入字節類型,都需要轉型
put.addColumn("cf1".getBytes(), "name".getBytes(), "張三".getBytes());
put.addColumn("cf1".getBytes(), "age".getBytes(), "18".getBytes());
put.addColumn("cf1".getBytes(), "clazz".getBytes(), "文科一班".getBytes());
put.addColumn("cf1".getBytes(), "clazz".getBytes(), 1, "文科二班".getBytes());//還可以傳入一個時間戳ts=1
//調取put()方法來執行
testAPI.put(put);
}
@Test
// get
public void GetData() throws IOException {
//獲取想要查詢數據的表,參數需要傳入TableName類型
Table testAPI = conn.getTable(TableName.valueOf("testAPI"));
//創建Gut對象,參數要求傳入一個rk的字節類型,需要轉型
Get get = new Get("001".getBytes());
//指定版本數量
get.setMaxVersions(10);
//調取get()方法來執行
Result rs = testAPI.get(get);
// 獲取rowkey
byte[] row = rs.getRow();
//獲取rowkey對應的value值
byte[] name = rs.getValue("cf1".getBytes(), "name".getBytes());
byte[] age = rs.getValue("cf1".getBytes(), "age".getBytes());
byte[] clazz = rs.getValue("cf1".getBytes(), "clazz".getBytes());
//輸出,將byte[]類型轉化為String類型
System.out.println(Bytes.toString(row) + "," + Bytes.toString(name) + "," + Bytes.toString(age) + "," + Bytes.toString(clazz));
}
@Test
// 提取數據的另一種方式----ListCells方法(Hbase提供)
public void ListCells() throws IOException {
//獲取想要查詢數據的表,參數需要傳入TableName類型
Table testAPI = conn.getTable(TableName.valueOf("testAPI"));
//創建Gut對象,參數要求傳入一個rk的字節類型,需要轉型
Get get = new Get("001".getBytes());
//指定版本數量
get.setMaxVersions(10);
//調取get()方法來執行
Result rs = testAPI.get(get);
// 獲取所有的Cell
List<Cell> cells = rs.listCells();
//遍歷Cell
for (Cell cell : cells) {
//將Cell中的數據提取出來
byte[] bytes = CellUtil.cloneValue(cell);
//將byte[]類型轉化為String類型
String value = Bytes.toString(bytes);
//輸出
System.out.println(value);
}
}
@After
public void close() throws IOException {
//關閉連接
conn.close();
}
}
3、程序案例----將學生表的數據通過代碼加載到表里(1000條數據)
- 方法一:逐條插入
package com.shujia;
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.*;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo3API {
Connection conn;
@Before
public void init() throws IOException {
//1、創建配置文件,設置HBase的連接地址(ZK的地址)
Configuration conf = HBaseConfiguration.create();
//第1個參數在 hbase-1.4.6/conf/hbase-site.xml 中,第2個參數需要我們自己指定
conf.set("hbase.zookeeper.quorum", "master:2181,note01:2181,note2:2181");
//2、建立連接(參數為配置對象的變量)
conn = ConnectionFactory.createConnection(conf);
}
@Test
/**
* 創建stu表,增加一個info列簇,將students.txt的1000條數據全部插入
*/
public void PutStu() throws IOException {
TableName stu = TableName.valueOf("stu");
// 創建表
Admin admin = conn.getAdmin();
if (!admin.tableExists(stu)) {
admin.createTable(new HTableDescriptor(stu)//創建表
.addFamily(new HColumnDescriptor("info")));//添加列簇
}
//讀取文件
FileReader fr = new FileReader("data/students.txt");
BufferedReader br = new BufferedReader(fr);
//和表建立連接
Table stuTable = conn.getTable(stu);
//提取數據
String line;
while ((line = br.readLine()) != null) {
//切分數據
String[] split = line.split(",");
String id = split[0];
String name = split[1];
String age = split[2];
String gender = split[3];
String clazz = split[4];
//創建Put對象,參數要求傳入一個rk的字節類型,需要轉型
Put put = new Put(id.getBytes());
//插入數據,需要傳入字節類型,都需要轉型
put.addColumn("info".getBytes(), "name".getBytes(), name.getBytes());
put.addColumn("info".getBytes(), "age".getBytes(), age.getBytes());
put.addColumn("info".getBytes(), "gender".getBytes(), gender.getBytes());
put.addColumn("info".getBytes(), "clazz".getBytes(), clazz.getBytes());
//調取put()方法來執行,逐條插入
//stuTable.put(put);
}
br.close();
}
@After
public void close() throws IOException {
//關閉連接
conn.close();
}
}
-
方法二:批量插入
逐條插入,據一共有一千條,相當於put了一千次,效率是非常低的
package com.shujia;
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.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Demo3API {
Connection conn;
@Before
public void init() throws IOException {
//1、創建配置文件,設置HBase的連接地址(ZK的地址)
Configuration conf = HBaseConfiguration.create();
//第1個參數在 hbase-1.4.6/conf/hbase-site.xml 中,第2個參數需要我們自己指定
conf.set("hbase.zookeeper.quorum", "master:2181,note01:2181,note2:2181");
//2、建立連接(參數為配置對象的變量)
conn = ConnectionFactory.createConnection(conf);
}
@Test
/**
* 創建stu表,增加一個info列簇,將students.txt的1000條數據全部插入
*/
public void PutStu() throws IOException {
TableName stu = TableName.valueOf("stu");
// 創建表
Admin admin = conn.getAdmin();
if (!admin.tableExists(stu)) {
admin.createTable(new HTableDescriptor(stu)//創建表
.addFamily(new HColumnDescriptor("info")));//添加列簇
}
//new一個ArrayList,泛型為Put
ArrayList<Put> puts = new ArrayList<>();
int cnt = 0;
//讀取文件
FileReader fr = new FileReader("data/students.txt");
BufferedReader br = new BufferedReader(fr);
//和表建立連接
Table stuTable = conn.getTable(stu);
//提取數據
String line;
while ((line = br.readLine()) != null) {
//切分數據
String[] split = line.split(",");
String id = split[0];
String name = split[1];
String age = split[2];
String gender = split[3];
String clazz = split[4];
//創建Put對象,參數要求傳入一個rk的字節類型,需要轉型
Put put = new Put(id.getBytes());
//插入數據,需要傳入字節類型,都需要轉型
put.addColumn("info".getBytes(), "name".getBytes(), name.getBytes());
put.addColumn("info".getBytes(), "age".getBytes(), age.getBytes());
put.addColumn("info".getBytes(), "gender".getBytes(), gender.getBytes());
put.addColumn("info".getBytes(), "clazz".getBytes(), clazz.getBytes());
// 批量插入(本次設置100條插入一次到表里)
puts.add(put);//將數據存放在集合里
cnt += 1; //存放一條,cnt加1
if (cnt == 100) {
stuTable.put(puts);//當cnt=100的時候,將集合里的數據加載到表里
puts.clear(); //集合是數據加載一次后,然后清空
cnt = 0;//插入一次后,cnt置零
}
}
// 判斷Put的List是否為空
if (!puts.isEmpty()) {
stuTable.put(puts);
}
br.close();
}
@Test
//刪除列----delete
public void DeleteData() throws IOException {
Table stuTable = conn.getTable(TableName.valueOf("stu"));
Delete del = new Delete("1500100001".getBytes());
stuTable.delete(del);
}
@Test
// scan獲取一批數據
public void ScanData() throws IOException {
//scan是獲取表的數據,需要獲取表
Table stuTable = conn.getTable(TableName.valueOf("stu"));
Scan scan = new Scan();
scan.setLimit(10);//獲取10條數據
scan.withStartRow("1500100008".getBytes());//起始rk
scan.withStopRow("1500100020".getBytes());//截至rk
//調取getScanner()來執行
ResultScanner scanner = stuTable.getScanner(scan);
//遍歷
for (Result rs : scanner) {
String id = Bytes.toString(rs.getRow());//獲取row
//獲取value值
String name = Bytes.toString(rs.getValue("info".getBytes(), "name".getBytes()));
String age = Bytes.toString(rs.getValue("info".getBytes(), "age".getBytes()));
String gender = Bytes.toString(rs.getValue("info".getBytes(), "gender".getBytes()));
String clazz = Bytes.toString(rs.getValue("info".getBytes(), "clazz".getBytes()));
System.out.println(id + "," + name + "," + age + "," + gender + "," + clazz);
}
}
@After
public void close() throws IOException {
//關閉連接
conn.close();
}
}