hbase小干货来了!!!
现在竟然还有人用idea建立maven项目导依赖包,建议还是直接在pom文件上添加依赖即可,方便,还不需要解压一个hbase包,难道不美滋滋吗?
下面这个是我的pom文件的依赖:
上图左边两个小文件都是Linux下的hbase安装包下提取的,为的就是方便连接zookeeper和控制台输出减少info级别的日志;哈哈哈其实就是懒惰;
然后我的java代码是一个个单元来测试的,因此在测试单元前面需要获得一些资源,而且在测试单元也需要用到,因此就有了@Before单元了;
然后因为admin是一个资源嘛,每次用完了都有必要去关闭资源,因此也有了@after单元;
为什么用测试单元呢?
把一种方法代码一块块的进行测试,速度也比直接写一大堆东西到main方法要快;关键是能够更好的了解一个测试单元真正需要什么,什么又是不需要的(这个才是我用的关键)
怎么用测试单元,在@test注解左边有键,你点击即可,也可以左键。
下面是before和after的代码:
获取连接和关闭资源:
private Configuration conf;
private Connection connection;
private Admin admin;
@Before
public void getConnect() throws IOException {
//获取配置
conf = HBaseConfiguration.create();
//获取连接
connection = ConnectionFactory.createConnection(conf);
//获取管理员对象
admin = connection.getAdmin();
}
@After
public void stop() throws IOException {
admin.close();
}
好了,下面就是一些hbase代码和截图展示了!!
DDL:和表级别的操作(如果你不了解DDL的话,建议去了解一下,因为之前我不懂,有时候别人 说的时候就很懵逼)
- 判断hbase是否存在该表
@Test
//判断表是否存在
public void tableIsExistsNot() throws IOException {
String tableName = "demo01";
//tableExists方法即可知道是否存在该表
boolean exists = admin.tableExists(TableName.valueOf(tableName));
System.out.println(tableName + "表是否存在:" + exists);
System.out.println("没有的" + "表是否存在" + admin.tableExists(TableName.valueOf("no")));
}
结果展示:
- 创建表
@Test
//创建表
public void createTable() throws IOException {
//创建new表
String tableName = "2021";
//创建表需要的列族
String[] cfs ={
"info1","info2"
};
if (admin.tableExists(TableName.valueOf(tableName))){
System.out.println(tableName + "表已存在,无法再次创建表");
return;
}
//获取表描述器
HTableDescriptor ht = new HTableDescriptor(TableName.valueOf(tableName));
for (String cf : cfs) {
HColumnDescriptor hc = new HColumnDescriptor(cf);
//创建表需要列族,在表描述器里面调用方法生成列族
ht.addFamily(hc);
}
//创建表
admin.createTable(ht);
//判断是否已经创建表了
System.out.println(tableName + "表是否存在:" + admin.tableExists(TableName.valueOf(tableName)));
}
结果展示:
再次运行创建表单元:
因为存在2021表了,因此无法再次创建:
- 删除表操作:
//删除表
@Test
public void dropTable() throws IOException {
//加上命名空间
String tableNameString = "2021";
TableName tableName1 = TableName.valueOf(tableNameString);
boolean tableExists = admin.tableExists(tableName1);
//判断表是否存在
if (!tableExists){
System.out.println(tableNameString + "表不存在,无法删除");
return;
}
//使表下线
if (!admin.isTableDisabled(tableName1)){
admin.disableTable(tableName1);
}
//删除表
admin.deleteTable(tableName1);
System.out.println(tableNameString + "表已经删除");
//判断是否已经删除
System.out.println(tableNameString + "表是否存在:" + admin.tableExists(tableName1));
}
结果展示:
再次运行删表单元:
再次创建的时候,结果是无法删除,因为2021表都不存在;
- 创建命名空间:
@Test
//创建命名空间
public void createNameSpace() throws IOException {
String nameSpace = "One";
//获取命名空间描述器
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(nameSpace).build();
try {
//创建命名空间
admin.createNamespace(namespaceDescriptor);
} catch (NamespaceExistException e){
//捕捉异常
System.out.println("命名空间已存在");
} catch (IOException e) {
e.printStackTrace();
}
//该输出是表达:尽管命名空间已经存在,那你可以直接只命名空间里面操作,创建表等
System.out.println("hbase里面已经有该命名空间,但是我还能走到这");
结果展示:
再次运行创建命名空间的测试单元:
命名空间存在了,可以进去命名空间进行下一步操作,类似于创建表,删除表等操作。
总结:DML的操作离不开Admin对象,也就是说,表级别的操作是由Admin对象来操纵。但是Admin不是操作DDL的把柄。
删除表的时候要注意点,要先使表下线了才能够删除。
以上就是hbase的DDL操作!
华丽的分界线---------------------------------------------------------------------------------
下面就是hbase的DML操作,对数据的增删改查。
下面的代码的before和after的属性命名有点不同!
获取连接和关闭资源:
Configuration conf;
Connection conn;
Admin admin;
@Before
public void connect() throws IOException {
conf = HBaseConfiguration.create();
conn = ConnectionFactory.createConnection(conf);
admin = conn.getAdmin();
}
@After
public void stop() throws IOException {
admin.close();
- 往表里面添加数据:(多个版本添加)
添加数据前,表里面的数据为空的:
结果展示:
@Test
//往表里面插入数据,方式一,单个rowkey,在put对象添加多个列
public void putData1() throws IOException {
//表
String tableName = "New:new";
//行键
String rowKey = "k2021";
//列族
String columnFamily = "info2";
//列的限定符,即列
String qualifier = "date";
//值
String value = "李嘉仪";
String value1 = "lijiayi";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
//获取put对象,参数为rowkey
Put put = new Put(Bytes.toBytes(rowKey));
//给put对象赋值
put.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(qualifier),Bytes.toBytes(value));
put.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(qualifier),Bytes.toBytes(value1));
//插入数据
table.put(put);
//关闭资源
table.close();
}
结果展示:
2. 插入数据版本2
@Test
//往表里面插入数据,方式二,多个rowkey
public void putData2() throws IOException {
//表
String tableName = "New:new";
//行键
String[] rowKeylist = {"k001","k002","k003","k2021"};
String rowKey = "k2021";
//列族
String columnFamily = "info2";
//列的限定符,即列
String qualifity = "information1";
//值
String value = "李嘉仪";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
//获取put对象,参数为rowkey
List<Put> list = new ArrayList<Put>();
for (String s : rowKeylist) {
Put put = new Put(Bytes.toBytes(s));
list.add(put);
//给put对象赋值
put.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(qualifity),Bytes.toBytes(value));
//插入数据
table.put(list);
}
//关闭资源
table.close();
}
结果展示:
- 获取 数据1:
@Test
//从表获取数据,利用rowkey来获得所有数据
public void getData1() throws IOException {
String tableName = "New:new";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
String rowKey = "k001";
//利用rowkey来获得所有数据
String[] rowKeys = {"k001","k002","k003","k2021"};
for (String rowkey : rowKeys) {
//获取get对象
Get get = new Get(Bytes.toBytes(rowkey));
//获得该行键的所有数据
Result result = table.get(get);
//获取一个个cell单元格数据
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
System.out.println(
//用Cellutils类获得rowkey,cf,qualifier,value
"行键:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",列族:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",列:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
- 获取数据2:
@Test
//从rowkey和column family来获取数据
public void getData2() throws IOException {
String tableName = "New:new";
String[] rowKeys = {"k001","k002","k003","k2021"};
String cf = "info1";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
for (String rowKey : rowKeys) {
//获得get对象
Get get = new Get(Bytes.toBytes(rowKey));
//给get对象设置列族
get.addFamily(Bytes.toBytes(cf));
Result result = table.get(get);
for (Cell cell : result.rawCells()) {
System.out.println(
//用Cellutils类获得rowkey,cf,qualifier,value
"行键:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",列族:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",列:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
- 获取数据3(用集合来封装put对象):
@Test
//从rowkey和column family来获取数据,通过list方式而不是get参数
public void getData3() throws IOException {
String tableName = "New:new";
String[] rowKeys = {"k001","k002","k003","k2021"};
String cf = "info1";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
List<Get> list = new ArrayList<Get>();
for (String rowKey : rowKeys) {
Get get = new Get(Bytes.toBytes(rowKey));
get.addFamily(Bytes.toBytes(cf));
list.add(get);
}
Result[] results = table.get(list);
for (Result result : results) {
for (Cell cell : result.rawCells()) {
System.out.println(
//用Cellutils类获得rowkey,cf,qualifier,value
"行键:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",列族:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",列:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
和上面的效果一模一样!!!
- 全表扫描scan方式1:
@Test
//scan获取数据
public void scan() throws IOException {
String tableName = "New:new";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
//获取scan对象
Scan scan = new Scan();
//查询全表
for (Result result : table.getScanner(scan)) {
for (Cell cell : result.rawCells()) {
//打印结果
System.out.println(
"rowkey:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",cf:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",qualifier:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
所有的记录都会查询出来,并且显示的都是最新的记录
- scan获取区间数据:
@Test
//scan获取数据,有起始行和结束行,左开右闭
public void scan1() throws IOException {
String tableName = "New:new";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
//获取scan对象
Scan scan = new Scan(Bytes.toBytes("k001"),Bytes.toBytes("k2021"));
//查询全表
ResultScanner results = table.getScanner(scan);
for (Result result : results) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
//打印结果
System.out.println(
"rowkey:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",cf:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",qualifier:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
- 删除数据1:
@Test
//删除数据,删除相对应的列族:列限定符记录
public void deleteData() throws IOException {
String tableName = "New:new";
String rowKey = "k001";
String cf = "info2";
String qualifier = "information1";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
//创建delete对象
Delete delete = new Delete(Bytes.toBytes(rowKey));
//展示没有删除数据前的记录
ResultScanner scanner = table.getScanner(new Scan());
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
//打印结果
System.out.println(
"rowkey:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",cf:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",qualifier:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//按照列族:列限定符来删除数据
delete.addColumns(Bytes.toBytes(cf),Bytes.toBytes(qualifier));
//删除数据
table.delete(delete);
//展示删除数据后的记录
System.out.println("----删除数据后--------");
for (Result result : table.getScanner(new Scan())) {
for (Cell cell : result.rawCells()) {
//打印结果
System.out.println(
"rowkey:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",cf:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",qualifier:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
- 删除数据2:
@Test
//删除数据,整个列族删除
public void deleteData1() throws IOException {
String tableName = "New:new";
String rowKey = "k002";
String cf = "info1";
//获取表对象
Table table = conn.getTable(TableName.valueOf(tableName));
//创建delete对象
Delete delete = new Delete(Bytes.toBytes(rowKey));
//展示没有删除数据前的记录
ResultScanner scanner = table.getScanner(new Scan());
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
//打印结果
System.out.println(
"rowkey:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",cf:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",qualifier:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//按照列族:列限定符来删除数据
delete.addFamily(Bytes.toBytes(cf));
//删除数据
table.delete(delete);
//展示删除数据后的记录
System.out.println("----删除数据后--------");
for (Result result : table.getScanner(new Scan())) {
for (Cell cell : result.rawCells()) {
//打印结果
System.out.println(
"rowkey:" + Bytes.toString(CellUtil.cloneRow(cell)) +
",cf:" + Bytes.toString(CellUtil.cloneFamily(cell)) +
",qualifier:" + Bytes.toString(CellUtil.cloneQualifier(cell)) +
",value:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
//关闭资源
table.close();
}
结果展示:
DML总结:
由于是对表进行操作,所以首先得要获得表的连接;
获得表的对象不是用Admin对象了,而是用conn来获取对象;
hbase的改操作就是利用时间戳来添加数据,来覆盖即可达到修改的效果;
以上只是一小部分的API,也是最基础的,大家有问题可以在下方提问
有空看到必定回答!!
希望大家三连决胜!!!!