Hbase的Java api

1 、准备工作

创建Maven的Java项目并配置文件
导入依赖
<dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>1.2.1</version>
</dependency>

在window中hosts(要把所有的关于master的映射也配置上,否则无法连接)
192.168.49.150 hbase1
192.168.49.151 hbase2
192.168.49.152 hbase3
192.168.49.153 hbase4

2 、HBase服务的连接

/**
 * 连接到HBase的服务
 */
public class Demo1_Conn {
    public static void main(String[] args) throws IOException {
        //1. 获取连接配置对象
        Configuration configuration = new Configuration();
        //2. 设置连接hbase的参数
        configuration.set("hbase.zookeeper.quorum", "hbase2:2181,hbase3:2181,hbase4:2181");
        //3. 获取Admin对象
        HBaseAdmin hBaseAdmin = new HBaseAdmin(configuration);
        //4. 检验指定表是否存在,来判断是否连接到hbase
        boolean flag = hBaseAdmin.tableExists("ns1:user_info");
        //5. 打印
        System.out.println(flag);
    }
}

3 Namespace操作

3.1、设计模板类

/**
 * 操作namespace
 */
public class Demo2_Namespace {

    private  HBaseAdmin hBaseAdmin;

    @Before
    public void before() throws IOException {
        //1. 获取连接配置对象
        Configuration configuration = new Configuration();
        //2. 设置连接hbase的参数
        configuration.set("hbase.zookeeper.quorum", "hbase2:2181,hbase3:2181,hbase4:2181");
        //3. 获取Admin对象
        hBaseAdmin = new HBaseAdmin(configuration);
    }

    @After
    public void close() throws IOException {
        hBaseAdmin.close();
    }
}

3.2、创建Namespace

/**
 * 创建namespace
 */
@Test
public void createNamespace() throws IOException {
    //1. 创建namespace对象
    NamespaceDescriptor descriptor = NamespaceDescriptor.create("lixi").build();
    //2. 提交hbase中创建对象
    hBaseAdmin.createNamespace(descriptor);
}

3.3、解决连接对象过时问题

@Before
public void before2() throws IOException {
    //1. 获取连接配置对象
    Configuration configuration = new Configuration();
    //2. 设置连接hbase的参数
    configuration.set("hbase.zookeeper.quorum", "hbase2:2181,hbase3:2181,hbase4:2181");
    //3. 获取Admin对象
    Connection connection = ConnectionFactory.createConnection(configuration);
    hBaseAdmin = (HBaseAdmin) connection.getAdmin();
}

3.4、提取工具类

/**
 * HBase Client工具类
 */
public class HBaseUtils {
    private static final Logger logger = Logger.getLogger(HBaseUtils.class);
    private final static String CONNECT_KEY = "hbase.zookeeper.quorum";
    private final static String CONNECT_VALUE = "hbase2:2181,hbase3:2181,hbase4:2181";

    /**
     * 获取Admin对象
     */
    public static Admin getAdmin() {
        //1. 获取连接配置对象
        Configuration configuration = new Configuration();
        //2. 设置连接hbase的参数
        configuration.set(CONNECT_KEY, CONNECT_VALUE);
        //3. 获取Admin对象
        Connection connection = null;
        Admin admin = null;
        try {
            connection = ConnectionFactory.createConnection(configuration);
            admin = connection.getAdmin();
        } catch (IOException e) {
            logger.warn("连接HBase的时候异常!", e);
        }
        return admin;
    }

    public static void close(Admin admin) {
        if(null != admin) {
            try {
                admin.close();
                admin.getConnection().close();
            } catch (IOException e) {
                logger.warn("关闭admin的时候异常!", e);
            }
        }
    }
}

3.5、使用工具类操作Namespace对象——列举Namesapce

/**
* 列举namespace
*/
@Test
public void listNamesapce() throws IOException {
    //1. 获取admin对象
    Admin admin = HBaseUtils.getAdmin();
    //2. 获取namespace的所有描述器
    NamespaceDescriptor[] namespaceDescriptors = admin.listNamespaceDescriptors();
    //3. 遍历
    for (NamespaceDescriptor descriptor : namespaceDescriptors) {
    System.out.println(descriptor);
    }
    //4. 关闭
    HBaseUtils.close(admin);
}

3.6、列举Namespace对应的表名

@Test
public void listNamespaceTables() throws IOException {
    //1. 获取admin对象
    Admin admin = HBaseUtils.getAdmin();
    //2. 获取name所有的表名
    TableName[] tableNames = admin.listTableNamesByNamespace("ns1");
    //3. 遍历
    for(TableName tableName : tableNames) {
    System.out.println(tableName.getNameAsString());
    }
    //4. 关闭
    HBaseUtils.close(admin);
}

3.7、列举所有Namespace对应所有的表

/**
* 列举所有namesacpe对应表名
*/
@Test
public void listAllNamespaceTables() throws IOException {
    //1. 获取admin对象
    Admin admin = HBaseUtils.getAdmin();
    //2. 获取name所有的表名
    TableName[] tableNames = admin.listTableNames();
    //3. 遍历
    for(TableName tableName : tableNames) {
    System.out.println(tableName.getNameAsString());
    }
    //4. 关闭
    HBaseUtils.close(admin);
}

3.8、列出指定Namespace指定的表描述器

/**
* 列举所有namesacpe对应表描述器
*/
@Test
public void listAllNamespaceTableDescriptor() throws IOException {
    //1. 获取admin对象
    Admin admin = HBaseUtils.getAdmin();
    //2. 获取name所有的表名
    HTableDescriptor[] tableDescriptors = admin.listTableDescriptorsByNamespace("ns1");
    //3. 遍历
    for(HTableDescriptor descriptor : tableDescriptors) {
        System.out.println(descriptor.getTableName());
    }
    //4. 关闭
    HBaseUtils.close(admin);
}

3.9、删除Namespace

/**
* 删除namespace
* 只能删除空的namespace
*/
@Test
public void dropNamespace() throws IOException {
    //1. 获取admin对象
    Admin admin = HBaseUtils.getAdmin();
    //2. 删除
    admin.deleteNamespace("lee");
    //3. 关闭
    HBaseUtils.close(admin);
}

4 、Table DDL

4.1、模板类

/**
 *  Table's CRUD DDL
 */
public class Demo4_Table {
    Admin admin = HBaseUtils.getAdmin();
    @After
    public void after() {
        HBaseUtils.close(admin);
    }
}

4.2、建表

/**
* create 't2', {NAME => 'default', VERSIONS => 1}
*/
@Test
public void createTable() throws IOException {
    //1. 创建表描述器
    HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf("user_info"));
    //2. 创建列簇表述qi
    HColumnDescriptor columnDescriptor = new HColumnDescriptor("base_info");
    //2.1 设置列簇版本从1到5
    columnDescriptor.setVersions(1, 5);
    columnDescriptor.setTimeToLive(24*60*60); // 秒为单位
    //        columnDescriptor.setMinVersions(1);
    //        columnDescriptor.setMaxVersions(5);
    //        columnDescriptor.setBloomFilterType(BloomType.ROW);
    //        columnDescriptor.setDFSReplication(3); // 设置HBase数据存放的副本数
    HColumnDescriptor columnDescriptor2 = new HColumnDescriptor("extra_info");
    columnDescriptor2.setVersions(1, 5);
    columnDescriptor2.setTimeToLive(24*60*60); // 秒为单位
    //2.2 将列簇添加到表中
    tableDescriptor.addFamily(columnDescriptor);
    tableDescriptor.addFamily(columnDescriptor2);
    //3. 提交
    admin.createTable(tableDescriptor);
}

4.3、修改表1:如果直接修改之前的保存数据没有了,类似于sql的修改,应该先查后改

/**
* 修改表1
*
*/
@Test
public void modifyTable() throws IOException {
    //1. 创建表描述器
    TableName tableName = TableName.valueOf("user_info");
    HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);
    //2. 创建列簇表述qi
    HColumnDescriptor columnDescriptor = new HColumnDescriptor("lixi_info");
    //2.1 设置列簇版本从1到5
    columnDescriptor.setVersions(1, 5);
    columnDescriptor.setTimeToLive(24*60*60); // 秒为单位
    //2.2 将列簇添加到表中
    tableDescriptor.addFamily(columnDescriptor);
    //3. 提交
    admin.modifyTable(tableName, tableDescriptor);
}

4.4、修改表2

/**
* 修改表2 : 在原来的基础之上进行修改
*
*/
@Test
public void modifyTable2() throws IOException {
    //1. 创建表描述器
    TableName tableName = TableName.valueOf("user_info");
    HTableDescriptor tableDescriptor = admin.getTableDescriptor(tableName);
    //2. 创建列簇表述qi
    HColumnDescriptor columnDescriptor = new HColumnDescriptor("base_info");
    //2.1 设置列簇版本从1到5
    columnDescriptor.setVersions(1, 5);
    columnDescriptor.setTimeToLive(24*60*60); // 秒为单位
    //2.2 将列簇添加到表中
    tableDescriptor.addFamily(columnDescriptor);
    //3. 提交
    admin.modifyTable(tableName, tableDescriptor);
}

4.5、删除列簇1

/**
* 修改表,删除列簇
*/
@Test
public void deleteColumnFamily() throws IOException {
    //1. 创建表并删除列簇
    TableName tableName = TableName.valueOf("user_info");
    admin.deleteColumn(tableName, "lixi_info".getBytes());
}

4.6、删除列簇2

/**
* 删除列簇2
*/
@Test
public void deleteColumnFamily2() throws IOException {
    //1. 创建表描述器
    TableName tableName = TableName.valueOf("user_info");
    HTableDescriptor tableDescriptor = admin.getTableDescriptor(tableName);
    //2. 获取要删除的列簇描述器
    HColumnDescriptor columnDescriptor = tableDescriptor.removeFamily("base_info".getBytes());
    //3. 删除
    admin.modifyTable(tableName, tableDescriptor);
}

4.7、例举出某表的所有列簇

/**
* 例举出某表的所有列簇
*/
@Test
public void listColumnFamily() throws IOException {
    //1. 获取表描述器
    HTableDescriptor tableDescriptor = admin.getTableDescriptor(TableName.valueOf("user_info"));
    //2. 获取所有的列簇
    HColumnDescriptor[] columnFamilies = tableDescriptor.getColumnFamilies();
    //3. 遍历
    for(HColumnDescriptor columnDescriptor : columnFamilies) {
        System.out.println(columnDescriptor.getNameAsString());
        System.out.println(columnDescriptor.getBlocksize());
        System.out.println(columnDescriptor.getBloomFilterType());
    }
}

4.8、删除表

/**
* 删除表
*/
@Test
public void dropTable() throws IOException {
    TableName tableName = TableName.valueOf("t1");
    if(admin.tableExists(tableName)) {
        if (!admin.isTableDisabled(tableName)) {
            admin.disableTable(tableName);
        }
        admin.deleteTable(TableName.valueOf("t1"));
    }
}

5 Table DML

5.1、获取Table对象

public static Table getTable() {
    return getTable("ns1:user_info");
}

public static Table getTable(String tablename) {
    Table table = null;
    if(StringUtils.isNotEmpty(tablename)) {
        try {
            table = connection.getTable(TableName.valueOf(tablename));
        } catch (IOException e) {
            logger.warn("获取表产生异常!", e);
        }
    }
    return table;
}

public static void close(Table table) {
    if(table != null) {
        try {
            table.close();
        } catch (IOException e) {
            logger.warn("关闭table的时候产生异常!", e);
        }
    }
}

5.2、修改HBaseUtils

/**
 * HBase Client工具类
 */
public class HBaseUtils {

    private static final Logger logger = Logger.getLogger(HBaseUtils.class);

    private final static String CONNECT_KEY = "hbase.zookeeper.quorum";
    private final static String CONNECT_VALUE = "hbase2:2181,hbase3:2181,hbase4:2181";
    private static Connection connection;

    static {
        //1. 获取连接配置对象
        Configuration configuration = HBaseConfiguration.create();
        //2. 设置连接hbase的参数
        configuration.set(CONNECT_KEY, CONNECT_VALUE);
        //3. 获取connection对象
        try {
            connection = ConnectionFactory.createConnection(configuration);
        } catch (IOException e) {
            logger.warn("连接HBase的时候异常!", e);
        }
    }

    /**
     * 获取Admin对象
     */
    public static Admin getAdmin() {
        Admin admin = null;
        try {
            admin = connection.getAdmin();
        } catch (IOException e) {
            logger.warn("连接HBase的时候异常!", e);
        }
        return admin;
    }

    public static void close(Admin admin) {
        if(null != admin) {
            try {
                admin.close();
            } catch (IOException e) {
                logger.warn("关闭admin的时候异常!", e);
            }
        }
    }

    public static Table getTable() {
        return getTable("ns1:user_info");
    }

    public static Table getTable(String tablename) {
        Table table = null;
       if(StringUtils.isNotEmpty(tablename)) {
           try {
               table = connection.getTable(TableName.valueOf(tablename));
           } catch (IOException e) {
               logger.warn("获取表产生异常!", e);
           }
       }
       return table;
    }

    public static void close(Table table) {
        if(table != null) {
            try {
                table.close();
            } catch (IOException e) {
                logger.warn("关闭table的时候产生异常!", e);
            }
        }
    }
}

5.3、Put

/**
 *  DML
 */
public class Demo5_Table {
    Table table = HBaseUtils.getTable();

    @After
    public void after() {
        HBaseUtils.close(table);
    }
    /**
     * 插入数据
     */
    @Test
    public void putData() throws IOException {
        //1. 获取Table对象
        Table table = HBaseUtils.getTable();
        //2. 获取Put对象,通过rowkey指定
        Put put = new Put(Bytes.toBytes("003"));
        /*
         * 3. 设置插入的数据
         * 列簇、列名、value
         */
        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("name"), Bytes.toBytes("narudo"));
        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes("15"));
        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("sex"), Bytes.toBytes("male"));
        //4. 提交
        table.put(put);
    }
}

5.4、批量插入数据

/**
* 批量插入数据
*/
@Test
public void batchPutDatas() throws IOException {
    //0. 创建集合
    List<Put> list = new ArrayList<>();

    //1. 创建put对象指定行键
    Put rk004 = new Put(Bytes.toBytes("004"));
    Put rk005 = new Put(Bytes.toBytes("005"));
    Put rk006 = new Put(Bytes.toBytes("006"));

    //2. 创建列簇
rk004.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("name"),Bytes.toBytes("gaoyuanyuan"));
    rk005.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("age"),Bytes.toBytes("18"));
    rk005.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("sex"),Bytes.toBytes("2"));
    rk006.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("name"),Bytes.toBytes("fanbinbin"));
    rk006.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("age"),Bytes.toBytes("18"));
    rk006.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("sex"),Bytes.toBytes("2"));

    //3. 添加数据
    list.add(rk004);
    list.add(rk005);
    list.add(rk006);

    table.put(list);
}

5.5、Get查询 : 查询单个列簇的所有列

/**
* get查询数据
*/
@Test
public void getData() throws IOException {
    //1. 获Get对象
    Get get = new Get(Bytes.toBytes("003"));
    //2. 通过table获取结果对象
    Result result = table.get(get);
    //3. 获取指定列簇的map集合
    NavigableMap<byte[], byte[]> base_info = result.getFamilyMap(Bytes.toBytes("base_info"));
    //4. 遍历map
    for(Map.Entry<byte[], byte[]> entry : base_info.entrySet()) {
        String k = new String(entry.getKey());
        String v = new String(entry.getValue());
        System.out.println(k + "=" + v);
    }
}

5.6、Get查询 : 获取rowkey对应的所有的列簇

/**
* get查询数据
*/
@Test
public void getData2() throws IOException {
    //1. 获Get对象
    Get get = new Get(Bytes.toBytes("003"));
    //2. 通过table获取结果对象
    Result result = table.get(get);
    //3. 获取表格扫描器
    CellScanner cellScanner = result.cellScanner();
    System.out.println("rowkey : " + result.getRow());
    //4. 遍历
    while (cellScanner.advance()) {
        //5. 获取当前表格
        Cell cell = cellScanner.current();
        //5.1 获取所有的列簇
        byte[] familyArray = cell.getFamilyArray();
        System.out.println(new String(familyArray, cell.getFamilyOffset(), cell.getFamilyLength()));
        //5.2 获取所有列
        byte[] qualifierArray = cell.getQualifierArray();
        System.out.println(new String(qualifierArray, cell.getQualifierOffset(), cell.getQualifierLength()));
        //5.3 获取所有的值
        byte[] valueArray = cell.getValueArray();
        System.out.println(new String(valueArray, cell.getValueOffset(), cell.getValueLength()));
    }
}

5.7、Get查询 : 第三种打印列的方式

/**
* get查询数据
*/
@Test
public void getData2() throws IOException {
    //1. 获Get对象
    Get get = new Get(Bytes.toBytes("003"));
    //2. 通过table获取结果对象
    Result result = table.get(get);
    //3. 获取表格扫描器
    CellScanner cellScanner = result.cellScanner();
    System.out.println("rowkey : " + result.getRow());
    //4. 遍历
    while (cellScanner.advance()) {
        //5. 获取当前表格
        Cell cell = cellScanner.current();
        //5.1 获取所有的列簇
        System.out.println(new String(CellUtil.cloneFamily(cell), "utf-8"));
        System.out.println(new String(CellUtil.cloneQualifier(cell), "utf-8"));
        System.out.println(new String(CellUtil.cloneValue(cell), "utf-8"));
    }
}

5.8、批量Get查询

**
* get查询数据
*/
@Test
public void batchGetData() throws IOException {
    //1. 创建集合存储get对象
    List<Get> gets = new ArrayList<>();
    //2. 创建多个get对象
    Get get = new Get(Bytes.toBytes("001"));
    get.addColumn(Bytes.toBytes("extra_info"),Bytes.toBytes("height"));
    get.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("sex"));

    Get get1 = new Get(Bytes.toBytes("002"));
    get1.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("name"));
    get1.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("age"));

    Get get2 = new Get(Bytes.toBytes("003"));
    get2.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("sex"));
    get2.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("age"));

    Get get3 = new Get(Bytes.toBytes("004"));
    //3. 添加get对象到集合中
    gets.add(get);
    gets.add(get1);
    gets.add(get2);
    gets.add(get3);

    //4. 将集合对象添加到表中
    Result[] results = table.get(gets);

    //5. 遍历
    for(Result result : results) {
        HBaseUtils.showResult(result);
    }
}

5.9、修改HBaseUtils

public static void showResult(Result result){
    CellScanner cellScanner = result.cellScanner();
    System.out.print("rowKey: " + Bytes.toString(result.getRow()));
    try {
        while (cellScanner.advance()){
            Cell current = cellScanner.current();

            System.out.print("\t" + new String(CellUtil.cloneFamily(current),"utf-8"));
            System.out.print(" : " + new String(CellUtil.cloneQualifier(current),"utf-8"));
            System.out.print("\t" + new String(CellUtil.cloneValue(current),"utf-8"));
        }
    } catch (UnsupportedEncodingException e) {
        logger.error("判断是否有下一个单元格失败!",e);
    } catch (IOException e) {
        logger.error("克隆数据失败!",e);
    }
}

5.10、Scan查询:扫描指定的表

/**
* 扫描表
*/
@Test
public void scanTable() throws IOException {
    //1. 创建扫描器
    Scan scan = new Scan();
    //2. 添加扫描的行数包头不包尾
    scan.setStartRow(Bytes.toBytes("001"));
    scan.setStopRow(Bytes.toBytes("006" + "\001"));  //小技巧
    //3. 添加扫描的列
    scan.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("name"));
    //4. 获取扫描器
    ResultScanner scanner = table.getScanner(scan);
    Iterator<Result> it = scanner.iterator();
    while (it.hasNext()){
        Result result = it.next();
        HBaseUtils.showResult(result);
    }
}

5.11、删除数据

/**
* 删除数据
*/
@Test
public void deleteData() throws IOException {
    //1. 创建集合用于批量删除
    List<Delete> dels = new ArrayList<>();
    //2. 创建删除数据对象
    Delete del = new Delete(Bytes.toBytes("004"));
    del.addColumn(Bytes.toBytes("base_info"),Bytes.toBytes("name"));
    //3. 添加到集合
    dels.add(del);
    //4. 提交
    table.delete(dels);
}