java的API基本操作-增删改查
基本思路
- 开始先配置、连接,最后关闭,这是通用的。
- 增删改查,都是获得对应的对象,put delete put get/scan,获得对象时可以用family/column等API进行进一步现在或过滤
- 然后用table对象加载之前的对象即可。
创建表
/**
* 创建一张表 myuser 两个列族 f1 f2
*/
@Test
public void createTable() throws IOException {
//连接HBase集群不需要指定HBase主节点的ip地址和端口号
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum","node01:2181,node02:2181,
node03:2181");
//创建连接对象
Connection connection = ConnectionFactory.
createConnection(configuration);
//获取连接对象,创建一张表
//获取管理员对象,来对手数据库进行DDL的操作
Admin admin = connection.getAdmin();
//指定我们的表名
TableName myUser = TableName.valueOf("myUser");
HTableDescriptor hTableDescriptor = new HTableDescriptor(myUser);
//指定两个列族
HColumnDescriptor f1 = new HColumnDescriptor("f1");
HColumnDescriptor f2 = new HColumnDescriptor("f2");
hTableDescriptor.addFamily(f1);
hTableDescriptor.addFamily(f2);
admin.createTable(hTableDescriptor);
admin.close();
connection.close();
}
初始化和关闭资源(抽出来,精简下面操作的代码)
@Before
public void initTable() throws IOException {
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum","node01:2181,
node02:2181,node03:2181");
connection = ConnectionFactory.createConnection(configuration);
table = connection.getTable(TableName.valueOf(TABLE_NAME));
}
@After
public void close() throws IOException {
table.close();
connection.close();
}
添加数据
- 增加输出和删除数据都是使用put。
- 有数据则修改,没数据则新增
/**
* 向myuser表当中添加数据 使用put对象
* 所有数据都是二进制数组
*/
@Test
public void addData() throws IOException {
Table table = connection.getTable(TableName.valueOf(TABLE_NAME));
//创建put对象,并制定rowkey的值
Put put = new Put("rk0001".getBytes());
//通过rowkey + 列族 + 列名 + 值 添加数据到具体cell
put.addColumn("f1".getBytes(),"name".getBytes(),"zhangsan".getBytes());
put.addColumn("f1".getBytes(),"age".getBytes(), Bytes.toBytes(18));
put.addColumn("f1".getBytes(),"id".getBytes(), Bytes.toBytes(25));
put.addColumn("f1".getBytes(),"address".getBytes(), Bytes.toBytes("testData));
table.put(put);
table.close();
}
查询数据
get查询:精准查询
/**
* 通过get对象 获取
*/
@Test
public void getData() throws IOException {
Get get = new Get("rk0001".getBytes());
//查询f1列族下的所有的列的值
//Get getNew = get.addFamily("f1".getBytes());
//查询f1列族下, phone这个字段(列)下所有的值
// Get getNew = get.addColumn("f2".getBytes(),"phone".getBytes());
//也可以直接链式调用
// Get get = new Get("rk0001".getBytes()).addColumn("f1".getBytes(),"name".getBytes());
//将所有的字段的数据都封装到result里面了
Result result = table.get(get);
//获取一条数据所有的cell,所有的值封装在cell里了
List<Cell> cells = result.listCells();
for (Cell cell : cells) {
//通过CellUtil工具类 获取对应的字符数组
byte[] family_name = CellUtil.cloneFamily(cell);
byte[] column_name = CellUtil.cloneQualifier(cell);
byte[] rowkey = CellUtil.cloneRow(cell);
byte[] cell_value = CellUtil.cloneValue(cell);
//根据字段的数据类型,使用对应的转换方法,得到对应的值
if ("age".equals(Bytes.toString(column_name))||
"id".equals(Bytes.toString(column_name))){
System.out.println("family_name : " + Bytes.toString(family_name));
System.out.println("column_name : " + Bytes.toString(column_name));
System.out.println("rowkey : " + Bytes.toString(rowkey));
//age或id的值是int类型,得用Bytes.toInt
System.out.println("cell_value : " + Bytes.toInt(cell_value));
}else{
System.out.println("family_name : " + Bytes.toString(family_name));
System.out.println("column_name : " + Bytes.toString(column_name));
System.out.println("rowkey : " + Bytes.toString(rowkey));
System.out.println("cell_value : " + Bytes.toString(cell_value));
}
table.close();
}
}
- 查询结果:
scan查询:范围查询
scan范围查询得到的数据量可能非常大,为了防止JVM OOM等异常,有一些限制API可以使用。多个限制条件一起使用,取交集
- setCaching:设置一次读取的
result
- 一个
result
可以理解成一条数据的封装,里面可能含有family column cell等数据,具体内容决定于搜索条件
- 一个
- setBatch:此方法设置用户获得的result中最多包含的
cell
个数;- 假设一个不设限制的result中有5个cell,setBatch(2),那么需要封装3个result,分别包含2、2、1个cell
- setCacheBlocks:将结果缓存 先去缓存读取数据,缓存没有数据才去服务端读取
- setMaxResultSize:单次rpc操作最多拿到
maxResultSize
字节的结果(result)集 - setMaxVersions:获得每个cell的最新的n个版本的值
@Test
public void scanData() throws IOException {
Scan scan = new Scan();//若没有指定startRow以及stopRow,则全表扫描
//扫描f1列族
//scan.addFamily("f1".getBytes());
//扫描 f2列族 phone列
//scan.addColumn("f2".getBytes(), "phone".getBytes());
//设置起始结束rowkey,前闭后开
//scan.setStartRow("0003".getBytes());
//scan.setStopRow("0007".getBytes());
//控制一次读取的数据量3个result 防止一次一个JVM读取太多OOM
scan.setCaching(3);
//此方法设置用户获得的result中最多包含的cell个数;一行数据中,可能有n个cell;n=5,setBatch(2),那么获得3个result,分别包含2、2、1个cell
scan.setBatch(2);
//将结果缓存 先去缓存读取数据,缓存没有数据才去服务端读取
scan.setCacheBlocks(true);
//单次rpc操作最多拿到maxResultSize字节的结果(result)集
scan.setMaxResultSize(1024);
//获得每个cell的最新的n个版本的值
scan.setMaxVersions(2);
//通过getScanner查询获取到了表里面所有的数据,是多条数据
ResultScanner scanner = table.getScanner(scan);
//遍历ResultScanner 得到每一条数据,每一条数据都是封装在result对象里面了
for (Result result : scanner) {
List<Cell> cells = result.listCells();
for (Cell cell : cells) {
byte[] family_name = CellUtil.cloneFamily(cell);
byte[] qualifier_name = CellUtil.cloneQualifier(cell);
byte[] rowkey = CellUtil.cloneRow(cell);
byte[] value = CellUtil.cloneValue(cell);
//判断id和age字段,这两个字段是整形值
if ("age".equals(Bytes.toString(qualifier_name)) || "id".equals(Bytes.toString(qualifier_name))) {
System.out.println("数据的rowkey为" + Bytes.toString(rowkey) + "======数据的列族为" + Bytes.toString(family_name) + "======数据的列名为" + Bytes.toString(qualifier_name) + "==========数据的值为" + Bytes.toInt(value));
} else {
System.out.println("数据的rowkey为" + Bytes.toString(rowkey) + "======数据的列族为" + Bytes.toString(family_name) + "======数据的列名为" + Bytes.toString(qualifier_name) + "==========数据的值为" + Bytes.toString(value));
}
}
}
}
- 部分结果:
删除数据
删除数据
- deleteColumn实际底层调用的是add相关API,最终调用put
/**
* 删除数据,使用delete对象
*
*/
@Test
public void deleteData() throws IOException {
//删除rowkey指定数据
Delete delete = new Delete("rk0002".getBytes());
//删除指定cell指定版本数据
//delete.deleteColumn("f1".getBytes(), "name".getBytes(), 1);
table.delete(delete);
}
//源码
@Deprecated
public Delete deleteColumn(byte [] family, byte [] qualifier,
long timestamp) {
return addColumn(family, qualifier, timestamp);
}
删除表
/**
* 删除表
*/
@Test
public void deleteTable() throws IOException {
//获取管理员对象,用于表的删除
Admin admin = connection.getAdmin();
//删除一张表之前,需要先禁用表
admin.disableTable(TableName.valueOf(TABLE_NAME));
admin.deleteTable(TableName.valueOf(TABLE_NAME));
}