HBase- 3 java的API基本操作-增删改查

    技术2024-03-15  90

    java的API基本操作-增删改查

    基本思路创建表初始化和关闭资源(抽出来,精简下面操作的代码)添加数据查询数据get查询:精准查询scan查询:范围查询 删除数据删除数据删除表 官网链接

    基本思路

    开始先配置、连接,最后关闭,这是通用的。增删改查,都是获得对应的对象,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)); }

    官网链接

    官网链接

    Processed: 0.016, SQL: 9