逐步掌握HBase的Java API常用操作

引入依赖

首先需要引入HBase相关依赖

		<dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>1.2.4</version>
        </dependency>

连接工具类

连接工具类需要设计成单例的,创建完成之后整个生命周期都可以使用

因为获取连接比较耗时,所以使用饿汉式一开始就创建了
定义两个静态的方法,分别用于获取连接和获取表

  • 针对表结构的操作,获取连接进行操作
  • 针对表内的操作,可以直接获取表进行操作
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
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;

/**
 * 〈获取连接的单例的类〉
 * 因为连接是贯穿整个操作的,所以采用饿汉式直接就创建了单例
 * 不常用的可以用静态内部类,枚举类或者双重锁创建懒汉式单例
 *
 * @author Chkl
 * @create 2020/5/5
 * @since 1.0.0
 */
public class HBaseConn {
    private static final HBaseConn INSTANCE = new HBaseConn();
    private static Configuration configuration;
    private static Connection connection;
	//构造方法中初始化连接配置
    private HBaseConn() {
        try {
            if (configuration == null) {
                configuration = HBaseConfiguration.create();
                configuration.set("hbase.zookeeper.quorum", "localhost");
                configuration.set("hbase.zookeeper.property.clientPort", "2181");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
	//通过工厂方法创建连接
    private Connection getConnection() {
        if (connection == null || connection.isClosed()) {
            try {
                connection = ConnectionFactory.createConnection(configuration);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return connection;
    }
	//获取连接
    public static Connection getHBaseConn() {
        return INSTANCE.getConnection();
    }
	//获取表对象
    public static Table getTable(String tableName) throws IOException {
        return INSTANCE.getConnection().getTable(TableName.valueOf(tableName));
    }
    //关闭连接
    public static void closeConn(){
        if (connection!=null){
            try {
                connection.close();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

基础工具类

  1. 创建表
	 /**
     * 创建Hbase表
     *
     * @param tableName 表名
     * @param cfs       列族数组
     * @return 是否创建成功
     */
    public static boolean createTable(String tableName, String[] cfs) {
        try (HBaseAdmin admin = (HBaseAdmin) HBaseConn.getHBaseConn().getAdmin()) {
            if (admin.tableExists(tableName)) {//表已经存在
                return false;
            }
            HTableDescriptor tableDescriptor =
                    new HTableDescriptor(TableName.valueOf(tableName));
            Arrays.stream(cfs).forEach(cf -> {//遍历列族数组
                HColumnDescriptor columnDescriptor = new HColumnDescriptor(cf);
                columnDescriptor.setMaxVersions(1);//设置版本数量
                tableDescriptor.addFamily(columnDescriptor);
            });
            admin.createTable(tableDescriptor);//创建表
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
  1. 删除表
	public static boolean deleteTable(String tableName){
        try (HBaseAdmin admin = (HBaseAdmin) HBaseConn.getHBaseConn().getAdmin()) {
            admin.disableTable(tableName);//disable表
            admin.deleteTable(tableName);//删除表
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
  1. 插入数据
	/**
     * hbase中插入一条数据
     *
     * @param tableName 表名
     * @param rowKey    唯一标识
     * @param cfName    列族名
     * @param qualifier 列名
     * @param data      数据
     * @return 是否插入成功
     */
    public static boolean putRow(String tableName, String rowKey,
                                 String cfName, String qualifier, String data) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Put put = new Put(Bytes.toBytes(rowKey));//创建put对象
            put.addColumn(Bytes.toBytes(cfName),
                    Bytes.toBytes(qualifier),
                    Bytes.toBytes(data));//封装put对象
            table.put(put);//put数据
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 插入多条数据
     *
     * @param tableName 表名
     * @param puts      封装好的put集合
     * @return 是否成功
     */
    public static boolean putRows(String tableName, List<Put> puts) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            table.put(puts);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
  1. 获取单条数据
 	/**
     * 获取单条数据
     *
     * @param tableName 表名
     * @param rowKey    唯一标识
     * @return 查询结果
     */
    public static Result getRow(String tableName, String rowKey) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Get get = new Get(Bytes.toBytes(rowKey));
            return table.get(get);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取单条数据
     *
     * @param tableName  表名
     * @param rowKey     唯一标识
     * @param filterList 过滤器
     * @return 查询结果
     */
    public static Result getRow(String tableName, String rowKey, FilterList filterList) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Get get = new Get(Bytes.toBytes(rowKey));
            get.setFilter(filterList);
            return table.get(get);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
  1. 通过scanner扫描表中数据
 	/**
     * 全表扫描
     *
     * @param tableName 表名
     * @return ResultScanner
     */
    public static ResultScanner getScanner(String tableName) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Scan scan = new Scan();
            scan.setCaching(1000);//缓存条数
            return table.getScanner(scan);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 带过滤器的扫描
     * @param tableName 表名
     * @param filterList 过滤器
     * @return ResultScanner
     */
    public static ResultScanner getScanner(String tableName,FilterList filterList) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Scan scan = new Scan();
            scan.setCaching(1000);//缓存条数
            scan.setFilter(filterList);
            return table.getScanner(scan);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 按区间扫描
     * @param tableName 表名
     * @param startKey 起始rowkey
     * @param endKey 终止rowKey
     * @return ResultScanner
     */
    public static ResultScanner getScanner(String tableName, String startKey, String endKey) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Scan scan = new Scan();
            scan.setCaching(1000);//缓存条数
            scan.setStartRow(Bytes.toBytes(startKey));
            scan.setStopRow(Bytes.toBytes(endKey));
            return table.getScanner(scan);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  带过滤器的按区间扫描
     * @param tableName 表名
     * @param startKey 起始rowkey
     * @param endKey 终止rowKey
     * @param filterList 过滤器
     * @return ResultScanner
     */
    public static ResultScanner getScanner(String tableName, String startKey, String endKey,
                                           FilterList filterList) {
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Scan scan = new Scan();
            scan.setCaching(1000);//缓存条数
            scan.setStartRow(Bytes.toBytes(startKey));
            scan.setStopRow(Bytes.toBytes(endKey));
            scan.setFilter(filterList);
            return table.getScanner(scan);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
  1. 删除行
	/**
     * hbase删除一行记录
     * @param tableName 表名
     * @param rowKey 唯一标识
     * @return 是否成功
     */
    public static boolean deleteRow(String tableName,String rowKey){
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Delete delete = new Delete(Bytes.toBytes(rowKey));
            table.delete(delete);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
  1. 删除列族
	/**
     * 删除列族
     * @param tableName 表名
     * @param cName 列族名
     * @return 是否成功
     */
    public static boolean deleteColumnFamily(String tableName,String cName){
        try (HBaseAdmin admin = (HBaseAdmin) HBaseConn.getHBaseConn().getAdmin()) {
           admin.deleteColumn(tableName,cName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
  1. 删除列
	/**
     * 删除列
     * @param tableName 表名
     * @param rowKey 唯一标识
     * @param cfName 列族名
     * @param qualifier 列名
     * @return
     */
    public static boolean deleteQualifier(String tableName,String rowKey,
                                          String cfName,String qualifier){
        try (Table table = HBaseConn.getTable(tableName)) {//创建table对象
            Delete delete = new Delete(Bytes.toBytes(rowKey));
            delete.addColumn(Bytes.toBytes(cfName),Bytes.toBytes(qualifier));
            table.delete(delete);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

基础工具类测试

  1. 创建表
	@Test
    public void createTable() {
        HBaseUtil.createTable("FileTable", new String[]{"fileInfo", "saveInfo"});
    }
  1. 添加数据
	 @Test
    public void addFile() {
        HBaseUtil.putRow("FileTable", "rowkey1", "fileInfo", "name", "file1.txt");
        HBaseUtil.putRow("FileTable", "rowkey1", "fileInfo", "type", "txt");
        HBaseUtil.putRow("FileTable", "rowkey1", "fileInfo", "size", "1024");
        HBaseUtil.putRow("FileTable", "rowkey1", "saveInfo", "creater", "klchen");
    }
  1. 获取一行数据
	 @Test
    public void getFileDetails() {
        Result result = HBaseUtil.getRow("FileTable", "rowkey1");
        if (result != null) {
            System.out.println("rowkey = "
                    + Bytes.toString(result.getRow()));
            System.out.println("fileName = "
                    + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
        }
    }
  1. scan扫描数据
	@Test
    public void scanFileDetails(){
        ResultScanner scanner = HBaseUtil.getScanner("FileTable", "rowkey1", "rowkey1");
        if (scanner!=null){
            scanner.forEach(result -> {
                System.out.println("rowkey = "
                        + Bytes.toString(result.getRow()));
                System.out.println("fileName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
            });
        }
        scanner.close();
    }
  1. 删除数据
	@Test
    public void deleteRow(){
        HBaseUtil.deleteRow("FileTable","rowkey1");
    }
  1. 删除表
	@Test
    public void deleteTable(){
        HBaseUtil.deleteTable("FileTable");
    }

HBase过滤器使用

基于结构的过滤器

  • 基于行的过滤器:
    • PrefixFilter 行前缀过滤器
    • PageFilter 基于行的分页
  • 基于列的过滤器
    • ColumnPrefixFilter 列前缀匹配
    • FirstKeyOnlyFilter 只返回每一行的第一列
  • 基于单元格的过滤器
    • KeyOnlyFilter 返回的数据不包括单元格值,只包含行键与列
    • TimestampsFilter 根据数据的时间戳版本进行过滤
  • 基于列和单元值的过滤器
    • SingleColumnValueFilter 对列的单元值进行比较过滤
    • SingleColumnValueExcludeFilter 对列的单元值进行比较过滤

基于比较的过滤器

  • RowFilter 行过滤器
  • FamilyFilter 列族过滤器
  • QualifierFilter 列过滤器
  • ValueFilter 值过滤器

常用过滤器
在这里插入图片描述
针对上面创建的基础工具类测试几种常见的过滤器

首先创建表添加测试数据

	@Test
    public void createTable() {
        HBaseUtil.createTable("FileTable", new String[]{"fileInfo", "saveInfo"});
    }

    @Test
    public void addFile() {
        HBaseUtil.putRow("FileTable", "rowkey1", "fileInfo", "name", "file1.txt");
        HBaseUtil.putRow("FileTable", "rowkey1", "fileInfo", "type", "txt");
        HBaseUtil.putRow("FileTable", "rowkey1", "fileInfo", "size", "1024");
        HBaseUtil.putRow("FileTable", "rowkey1", "saveInfo", "creater", "klchen");

        HBaseUtil.putRow("FileTable", "rowkey2", "fileInfo", "name", "file2.txt");
        HBaseUtil.putRow("FileTable", "rowkey2", "fileInfo", "type", "txt");
        HBaseUtil.putRow("FileTable", "rowkey2", "fileInfo", "size", "2048");
        HBaseUtil.putRow("FileTable", "rowkey2", "saveInfo", "creater", "klchen");

        HBaseUtil.putRow("FileTable", "rowkey3", "fileInfo", "name", "file3.txt");
        HBaseUtil.putRow("FileTable", "rowkey3", "fileInfo", "type", "txt");
        HBaseUtil.putRow("FileTable", "rowkey3", "fileInfo", "size", "512");
        HBaseUtil.putRow("FileTable", "rowkey3", "saveInfo", "creater", "klchen");

        HBaseUtil.putRow("FileTable", "rowkey4", "fileInfo", "name", "file4.txt");
        HBaseUtil.putRow("FileTable", "rowkey4", "fileInfo", "type", "txt");
        HBaseUtil.putRow("FileTable", "rowkey4", "fileInfo", "size", "4096");
        HBaseUtil.putRow("FileTable", "rowkey4", "saveInfo", "creater", "klchen");

    }
  1. RowFilter 行过滤器测试
    scan获取[rowkey1,rowkey3)的数据到缓存,匹配行键值为rowkey1的行,打印输出rowKeyfileName
	 /**
     * row过滤器,进行与rowkey相关的过滤
     * 可以大于,小于,大于等于,小于等于,等于
     */
    @Test
    public void rowFilterTest(){
        //行过滤器是基于比较的,所以添加一个比较规则
        RowFilter filter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("rowkey1")));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(filter));
        ResultScanner scanner = HBaseUtil.getScanner("FileTable", "rowkey1", "rowkey3", filterList);
        if (scanner!=null){
            scanner.forEach(result -> {
                System.out.println("rowkey = "
                        + Bytes.toString(result.getRow()));
                System.out.println("fileName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
            });
        }
        scanner.close();
    }

打印输出:

rowkey = rowkey1
fileName = file1.txt
  1. PrefixFilter 行前缀过滤器
    匹配行键前缀为rowkey1的行,预计只有一行
	/**
     * prefix过滤器,进行rowkey前缀为某个值的过滤
     */
    @Test
    public void prefixFilterTest(){
        PrefixFilter filter = new PrefixFilter(Bytes.toBytes("rowkey2"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(filter));
        ResultScanner scanner = HBaseUtil.getScanner("FileTable", "rowkey1", "rowkey3", filterList);
        if (scanner!=null){
            scanner.forEach(result -> {
                System.out.println("rowkey = "
                        + Bytes.toString(result.getRow()));
                System.out.println("fileName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
            });
        }
        scanner.close();
    }

打印输出:

rowkey = rowkey1
fileName = file1.txt
  1. 列前缀过滤器ColumnPrefixFilter
    获取列前缀为name的列的信息
    预测有两行数据,其中只有name列有值,其他列没有值
	/**
     * 列名前缀过滤器,过滤前缀为指定值的列
     */
    @Test
    public void columnPrefixFilterTest(){
        ColumnPrefixFilter filter = new ColumnPrefixFilter(Bytes.toBytes("name"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(filter));
        ResultScanner scanner = HBaseUtil.getScanner("FileTable", "rowkey1", "rowkey3", filterList);
        if (scanner!=null){
            scanner.forEach(result -> {
                System.out.println("rowkey = "
                        + Bytes.toString(result.getRow()));
                System.out.println("fileName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
                System.out.println("filetype = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("type"))));
            });
        }
        scanner.close();
    }

打印输出:

rowkey = rowkey1
fileName = file1.txt
filetype = null
rowkey = rowkey2
fileName = file2.txt
filetype = null
  1. KeyOnly过滤器
    匹配到之后只返回rowkey不返回单元格的值
	/**
     * KeyOnly过滤器,只返回rowkey的值不会返回实际存储的内容
     */
    @Test
    public void keyOnlyFilterTest(){
        KeyOnlyFilter filter = new KeyOnlyFilter(true);
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(filter));
        ResultScanner scanner = HBaseUtil.getScanner("FileTable", "rowkey1", "rowkey3", filterList);
        if (scanner!=null){
            scanner.forEach(result -> {
                System.out.println("rowkey = "
                        + Bytes.toString(result.getRow()));
                System.out.println("fileName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
            });
        }
        scanner.close();
    }

打印输出:
可以看到值有rowkey有值,单元格都没有值

rowkey = rowkey1
fileName =    	
rowkey = rowkey2
fileName =

5.ValueFilter 值过滤器
获取值为file2.txt的单元格

	/**
     * 值过滤器,获取值为某值的一条值
     */
    @Test
    public void valueFilterTest(){
        ValueFilter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("file2.txt")));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(filter));
        ResultScanner scanner = HBaseUtil.getScanner("FileTable", "rowkey1", "rowkey3", filterList);
        if (scanner!=null){
            scanner.forEach(result -> {
                System.out.println("rowkey = "
                        + Bytes.toString(result.getRow()));
                System.out.println("fileName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("name"))));
                System.out.println("filetype = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("fileInfo"), Bytes.toBytes("type"))));
            });
        }
        scanner.close();
    }

打印输出:
可以看出查询到的是单元格而不是行,只能查询出单元格的值

rowkey = rowkey2
fileName = file2.txt
filetype = null

综合案例

要求
1.建立命名空间(命名空间名自拟)
2.在该命名空间中建立满足以下要求的数据表(表名自拟)
3.在表中增加满足业务场景描述的数据(不少于10条)
4.完成以下查询操作

  • 查询所有一级部门(没有上级部门的部门)
  • 已知rowkey(自拟),查询该部门的所有(直接)子部门信息
  • 已知rowkey(自拟),向该部门增加一个子部门
  • 已知rowkey(自拟,且该部门存在子部门),删除该部门信息,该部门所有(直接)子部门被调整到其他部门(自拟)中。

设计

  1. 存储表设计
    创建表dept
    设置两个列族
    列族info,列deptName部门名称,detail备注,
    列族realation,列parent父部门编号
  2. rowKey设计
    假定部门等级共4级。每个部门的子部门个数不超过100,用8位数字充当rowKey
    一级部门编号为xx000000 其中xx是一级部门的编号
    二级部门编号为xxyy0000 其中yy是一级部门的编号,yy是一级部门下的二级部门的编号
    同理可得三级部门和四级部门的rowKey
    这样设计的好处:
  1. 长度原则:在假设情况下尽可能的将长度进行了压缩,虽然不是最短,但是也是相对较短的了
  2. 唯一原则:在满足假设的情况下,能保证rowkey的唯一
  3. 排序原则:RowKey是按照ASCII有序排序的,当查询某个部门的子部门时,所有的子部门是依次排列在一起的,分散度较小,特别是查询最低级部门时,查询结果的rowKey是连续的,可以快速的查询到子部门
  4. 散列原则:能做到均匀分布,不容易出现热点问题

编码

  1. 创建表
	/**
     * 创建命名空间dept
     * 创建表dept,列族info和parent
     */
    @Test
    public void createTable() {
        HBaseUtil.createTable("dept:dept", new String[]{"info", "realation"});
    }
  1. 插入数据
	/**
     * 按照规则插入207条数据
     */
    @Test
    public void addRows() {
        //添加2个顶级部门
        HBaseUtil.putRow("dept:dept", "10000000", "info", "deptName", "成都铁路局");
        HBaseUtil.putRow("dept:dept", "10000000", "info", "detail", "顶级部门");
        HBaseUtil.putRow("dept:dept", "10000000", "realation", "parent", "");

        HBaseUtil.putRow("dept:dept", "12000000", "info", "deptName", "郑州铁路局");
        HBaseUtil.putRow("dept:dept", "12000000", "info", "detail", "顶级部门");
        HBaseUtil.putRow("dept:dept", "12000000", "realation", "parent", "");

        //添加三个2级部门
        HBaseUtil.putRow("dept:dept", "10100000", "info", "deptName", "绵阳工务段");
        HBaseUtil.putRow("dept:dept", "10100000", "info", "detail", "工务段级");
        HBaseUtil.putRow("dept:dept", "10100000", "realation", "parent", "10000000");

        HBaseUtil.putRow("dept:dept", "10130000", "info", "deptName", "达州工务段");
        HBaseUtil.putRow("dept:dept", "10130000", "info", "detail", "工务段级");
        HBaseUtil.putRow("dept:dept", "10130000", "realation", "parent", "10000000");

        HBaseUtil.putRow("dept:dept", "10010000", "info", "deptName", "成都工务段");
        HBaseUtil.putRow("dept:dept", "10010000", "info", "detail", "工务段级");
        HBaseUtil.putRow("dept:dept", "10010000", "realation", "parent", "10000000");

        //在绵阳工务段下创建2个三级部门
        HBaseUtil.putRow("dept:dept", "10100600", "info", "deptName", "江油线路车间");
        HBaseUtil.putRow("dept:dept", "10100600", "info", "detail", "'线路车间");
        HBaseUtil.putRow("dept:dept", "10100600", "realation", "parent", "10100000");

        HBaseUtil.putRow("dept:dept", "10100700", "info", "deptName", "乐坝线路车间");
        HBaseUtil.putRow("dept:dept", "10100700", "info", "detail", "'线路车间");
        HBaseUtil.putRow("dept:dept", "10100700", "realation", "parent", "10100000");

        //在江油线路车间下创建100个四级部门
        for (int i = 0; i < 10; i++) {
            HBaseUtil.putRow("dept:dept", "1010060" + i, "info", "deptName", "江油线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "1010060" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "1010060" + i, "realation", "parent", "10100600");
        }
        for (int i = 10; i < 100; i++) {
            HBaseUtil.putRow("dept:dept", "101006" + i, "info", "deptName", "江油线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "101006" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "101006" + i, "realation", "parent", "10100600");
        }
        //在乐坝线路车间下创建100个四级部门
        for (int i = 0; i < 10; i++) {
            HBaseUtil.putRow("dept:dept", "1010070" + i, "info", "deptName", "乐坝线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "1010070" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "1010070" + i, "realation", "parent", "10100700");
        }
        for (int i = 10; i < 100; i++) {
            HBaseUtil.putRow("dept:dept", "101007" + i, "info", "deptName", "乐坝线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "101007" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "101007" + i, "realation", "parent", "10100700");
        }
    }
  1. 查询顶级部门
	/**
     * 查询parent列值为""的行为顶级部门
     * 同时使用值过滤器和列前缀过滤器
     */
    @Test
    public void selectTopDept() {
        ValueFilter valuefilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("")));
        ColumnPrefixFilter columnfilter = new ColumnPrefixFilter(Bytes.toBytes("parent"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(valuefilter, columnfilter));
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", filterList);
        if (scanner != null) {
            scanner.forEach(result -> {
                Result row = HBaseUtil.getRow("dept:dept", Bytes.toString(result.getRow()));
                System.out.print("rowkey = "
                        + Bytes.toString(row.getRow())+" , ");
                System.out.print("deptName = "
                        + Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("deptName")))+" , ");
                System.out.println("detail = "
                        + Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("detail"))));
            });
        }
        scanner.close();
    }
  1. 查询所有直接子部门
  /**
     * 获取10100600部门的所有子级部门信息
     */
    @Test
    public void selectChildren(){
        ValueFilter valuefilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("10100600")));
        ColumnPrefixFilter columnfilter = new ColumnPrefixFilter(Bytes.toBytes("parent"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(valuefilter, columnfilter));
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", filterList);
        if (scanner != null) {
            scanner.forEach(result -> {
                Result row = HBaseUtil.getRow("dept:dept", Bytes.toString(result.getRow()));
                System.out.print("rowkey = "
                        + Bytes.toString(row.getRow())+" , ");
                System.out.print("deptName = "
                        + Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("deptName")))+" , ");
                System.out.println("detail = "
                        + Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("detail"))));
            });
        }
        scanner.close();
    }

如果直接子部门时最低级部门时,可以不使用filter

	/**
     * 获取10100600部门的所有子级部门信息
     * 只针对直接子部门时最低一级的部门有效
     * 不用filter  直接获取区间内的sacn就可以了   快了很多!
     */
    @Test
    public void selectChildren2(){
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", "10100600","10100700");
        if (scanner != null) {
            scanner.forEach(result -> {
                System.out.print("rowkey = "
                        + Bytes.toString(result.getRow())+" , ");
                System.out.print("deptName = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("deptName")))+" , ");
                System.out.println("detail = "
                        + Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("detail"))));
            });
        }
        scanner.close();
    }
  1. 添加子部门
	 /**
     * 在成都工务段下添加一个子部门
     */
    @Test
    public void addChild(){
        HBaseUtil.putRow("dept:dept", "10010900", "info", "deptName", "双流线路车间");
        HBaseUtil.putRow("dept:dept", "10010900", "info", "detail", "线路车间");
        HBaseUtil.putRow("dept:dept", "10010900", "realation", "parent", "10010000");
    }
  1. 删除部门,将直接子部门转到其他部门
 	 /**
     * 删除部门10100600 ,将所有下级部门转给10100700
     */
    @Test
    public void deleteDept(){
        //删除部门10100600
        HBaseUtil.deleteRow("dept:dept","10100600");
        //将10100600的所有直接子部门转给10100700
        ValueFilter valuefilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("10100600")));
        ColumnPrefixFilter columnfilter = new ColumnPrefixFilter(Bytes.toBytes("parent"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(valuefilter, columnfilter));
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", filterList);
        if (scanner != null) {
            scanner.forEach(result -> {
                //hbase中没有修改操作,先删除后添加
                HBaseUtil.deleteQualifier("dept:dept",Bytes.toString(result.getRow()), "realation", "parent");
                HBaseUtil.putRow("dept:dept", Bytes.toString(result.getRow()), "realation", "parent", "10100700");
            });
        }
        scanner.close();
    }
  1. 删除表
	/**
     * 测试完毕,删除表,方便下次直接使用
     */
    @Test
    public void deleteTable() {
        HBaseUtil.deleteTable("dept:dept");
    }

改写成接口

为了让数据和操作能在界面上显示,将单元测试改写成接口

创建一个Spring Boot工程,添加web依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

编写接口实现

/**
 * 〈dept综合用例调用接口〉
 *
 * @author Chkl
 * @create 2020/5/5
 * @since 1.0.0
 */
@RestController
public class DeptController {

    /**
     * 创建命名空间dept
     * 创建表dept,列族info和parent
     */
    @RequestMapping("createTable")
    public void createTable() {
        HBaseUtil.createTable("dept:dept", new String[]{"info", "realation"});
    }

    /**
     * 按照规则插入207条数据
     */
    @RequestMapping("addRows")
    public void addRows() {
        //添加2个顶级部门
        HBaseUtil.putRow("dept:dept", "10000000", "info", "deptName", "成都铁路局");
        HBaseUtil.putRow("dept:dept", "10000000", "info", "detail", "顶级部门");
        HBaseUtil.putRow("dept:dept", "10000000", "realation", "parent", "");

        HBaseUtil.putRow("dept:dept", "12000000", "info", "deptName", "郑州铁路局");
        HBaseUtil.putRow("dept:dept", "12000000", "info", "detail", "顶级部门");
        HBaseUtil.putRow("dept:dept", "12000000", "realation", "parent", "");

        //添加三个2级部门
        HBaseUtil.putRow("dept:dept", "10100000", "info", "deptName", "绵阳工务段");
        HBaseUtil.putRow("dept:dept", "10100000", "info", "detail", "工务段级");
        HBaseUtil.putRow("dept:dept", "10100000", "realation", "parent", "10000000");

        HBaseUtil.putRow("dept:dept", "10130000", "info", "deptName", "达州工务段");
        HBaseUtil.putRow("dept:dept", "10130000", "info", "detail", "工务段级");
        HBaseUtil.putRow("dept:dept", "10130000", "realation", "parent", "10000000");

        HBaseUtil.putRow("dept:dept", "10010000", "info", "deptName", "成都工务段");
        HBaseUtil.putRow("dept:dept", "10010000", "info", "detail", "工务段级");
        HBaseUtil.putRow("dept:dept", "10010000", "realation", "parent", "10000000");

        //在绵阳工务段下创建2个三级部门
        HBaseUtil.putRow("dept:dept", "10100600", "info", "deptName", "江油线路车间");
        HBaseUtil.putRow("dept:dept", "10100600", "info", "detail", "'线路车间");
        HBaseUtil.putRow("dept:dept", "10100600", "realation", "parent", "10100000");

        HBaseUtil.putRow("dept:dept", "10100700", "info", "deptName", "乐坝线路车间");
        HBaseUtil.putRow("dept:dept", "10100700", "info", "detail", "'线路车间");
        HBaseUtil.putRow("dept:dept", "10100700", "realation", "parent", "10100000");

        //在江油线路车间下创建100个四级部门
        for (int i = 0; i < 10; i++) {
            HBaseUtil.putRow("dept:dept", "1010060" + i, "info", "deptName", "江油线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "1010060" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "1010060" + i, "realation", "parent", "10100600");
        }
        for (int i = 10; i < 100; i++) {
            HBaseUtil.putRow("dept:dept", "101006" + i, "info", "deptName", "江油线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "101006" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "101006" + i, "realation", "parent", "10100600");
        }
        //在乐坝线路车间下创建100个四级部门
        for (int i = 0; i < 10; i++) {
            HBaseUtil.putRow("dept:dept", "1010070" + i, "info", "deptName", "乐坝线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "1010070" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "1010070" + i, "realation", "parent", "10100700");
        }
        for (int i = 10; i < 100; i++) {
            HBaseUtil.putRow("dept:dept", "101007" + i, "info", "deptName", "乐坝线路车间测试工区" + i);
            HBaseUtil.putRow("dept:dept", "101007" + i, "info", "detail", "'线路工间");
            HBaseUtil.putRow("dept:dept", "101007" + i, "realation", "parent", "10100700");
        }
    }

    /**
     * 查询parent列值为""的行为顶级部门
     * 同时使用值过滤器和列前缀过滤器
     */
    @RequestMapping("selectTopDept")
    public Object selectTopDept() {
        ValueFilter valuefilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("")));
        ColumnPrefixFilter columnfilter = new ColumnPrefixFilter(Bytes.toBytes("parent"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(valuefilter, columnfilter));
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", filterList);
        List<DeptVo> res = new ArrayList<>();
        if (scanner != null) {
            scanner.forEach(result -> {
                Result row = HBaseUtil.getRow("dept:dept", Bytes.toString(result.getRow()));
                DeptVo deptVo = new DeptVo();
                deptVo.setRowkey(Bytes.toString(row.getRow()));
                deptVo.setDeptName(Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("deptName"))));
                deptVo.setDetail(Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("detail"))));
                res.add(deptVo);
            });
        }
        scanner.close();
        return res;
    }

    /**
     * 获取10100600部门的所有子级部门信息
     */
    @RequestMapping("selectChildren/{rowkey}")
    public Object selectChildren(@PathVariable String rowkey) {
        ValueFilter valuefilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(rowkey)));
        ColumnPrefixFilter columnfilter = new ColumnPrefixFilter(Bytes.toBytes("parent"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(valuefilter, columnfilter));
        List<DeptVo> res = new ArrayList<>();
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", filterList);
        if (scanner != null) {
            scanner.forEach(result -> {
                Result row = HBaseUtil.getRow("dept:dept", Bytes.toString(result.getRow()));
                DeptVo deptVo = new DeptVo();
                deptVo.setRowkey(Bytes.toString(row.getRow()));
                deptVo.setDeptName(Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("deptName"))));
                deptVo.setDetail(Bytes.toString(row.getValue(Bytes.toBytes("info"), Bytes.toBytes("detail"))));
                res.add(deptVo);
            });
        }
        scanner.close();
        return res;
    }



    /**
     * 在成都工务段下添加一个子部门
     */
    @RequestMapping("addChild")
    public void addChild(@RequestBody Dept dept) {
        HBaseUtil.putRow("dept:dept", dept.getRowkey(), "info", "deptName", dept.getDeptName());
        HBaseUtil.putRow("dept:dept", dept.getRowkey(), "info", "detail", dept.getDetail());
        HBaseUtil.putRow("dept:dept", dept.getRowkey(), "realation", "parent", dept.getParent());
    }

    /**
     * 删除部门10100600 ,将所有下级部门转给10100700
     */
    @RequestMapping("deleteDept/deleteDept/{deleteDept}/toDept/{toDept}")
    public void deleteDept(@PathVariable String deleteDept,
                           @PathVariable String toDept) {
        //删除部门10100600
        HBaseUtil.deleteRow("dept:dept", deleteDept);
        //将10100600的所有直接子部门转给10100700
        ValueFilter valuefilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(deleteDept)));
        ColumnPrefixFilter columnfilter = new ColumnPrefixFilter(Bytes.toBytes("parent"));
        //创建一个FilterList,设置规则为必须全部filter都通过才算通过
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays.asList(valuefilter, columnfilter));
        ResultScanner scanner = HBaseUtil.getScanner("dept:dept", filterList);
        if (scanner != null) {
            scanner.forEach(result -> {
                //hbase中没有修改操作,先删除后添加
                HBaseUtil.deleteQualifier("dept:dept", Bytes.toString(result.getRow()), "realation", "parent");
                HBaseUtil.putRow("dept:dept", Bytes.toString(result.getRow()), "realation", "parent", toDept);
            });
        }
        scanner.close();
    }

    /**
     * 测试完毕,删除表,方便下次直接使用
     */
    @RequestMapping("deleteTable")
    public void deleteTable() {
        HBaseUtil.deleteTable("dept:dept");
    }

}

猜你喜欢

转载自blog.csdn.net/qq_41170102/article/details/105999612
今日推荐