4.HBase-API
准备工作:
导包:hbase-client / hbase-common / hbase-server
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>1.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-client -->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-server -->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.2.0</version>
</dependency>
一、DDL操作
配置信息用到 HBaseConfiguration 类的 create方法;
获取连接用到 ConnectionFactory 类的 createConnection方法;
DDL操作都要用到 Admin 类的实例来完成。
public class TestAPI { private static Connection conn = null; private static Admin admin = null; static { try { // 1.获取配置文件信息 Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "192.168.131.200:2181"); conn = ConnectionFactory.createConnection(conf); // 2.获取管理员对象 admin = conn.getAdmin(); } catch (IOException e) { e.printStackTrace(); } } /* * todo: 关闭资源 * 只有当所有业务完成后才进行关闭操作 * */ public static void close() { if (admin != null) { try { admin.close(); } catch (IOException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (IOException e) { e.printStackTrace(); } } } /* todo: 1.判断表是否存在 */ public static boolean isTableExist(String tableName) throws Exception { TableName name = TableName.valueOf(tableName); boolean exists = admin.tableExists(name); return exists; } /* * todo: 2.创建表 * */ public static void createTable(String tableName, String... LieCu) throws Exception { // 1.先判断传参是否正确 if (LieCu.length <= 0) { System.out.println("请设置列簇信息"); return; } // 2.判断表是否存在 if (isTableExist(tableName)) { System.out.println(tableName + "表已经存在"); return; } // 3.创建表描述器 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName)); // 4.添加列簇进去 for (String lc : LieCu) { HColumnDescriptor hcd = new HColumnDescriptor(lc); htd.addFamily(hcd); } // 5.创建表 admin.createTable(htd); } public static void deleteTable(String tableName) throws Exception { // 1.先判断表是否存在 if (!isTableExist(tableName)) System.out.println(tableName + "表不存在"); // 2.先使表下线 admin.disableTable(TableName.valueOf(tableName)); // 3.删除表 admin.deleteTable(TableName.valueOf(tableName)); } /* * todo: 4.创建命名空间 * */ public static void createNameSpace(String namespace) { // 1.创建命名空间描述器 NamespaceDescriptor nsd = NamespaceDescriptor.create(namespace).build(); // 2.创建命名空间 try { admin.createNamespace(nsd); } catch (NamespaceExistException e) { System.out.println("命名空间已经存在"); } catch (IOException e) { e.printStackTrace(); } System.out.println("即使存在,代码还是可以继续往下执行"); } public static void main(String[] args) throws Exception { // 1.判断表是否存在 // System.out.println(isTableExist("zyp:mytest")); // 2.创建表 createTable("zyp:mytest","lc1","lc2","lc3"); // 3.删除表 // deleteTable("zyp:mytest"); // System.out.println(isTableExist("zyp:mytest")); // 4.创建命名空间 // createNameSpace("new"); // admin.deleteNamespace("new"); // 删除命名空间 close(); } }
二、DML操作
对比上面的DDL操作:
DDL在获取连接后需要用到 Admin 的实例来去进行,而DML则是需要在获取连接后,调用getTable 方法 ,获取到 Table 的实例来进行DML操作;
插入数据:
public class TestAPI { private static Connection conn = null; static { try { // 获取配置文件信息 Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "192.168.131.200:2181"); conn = ConnectionFactory.createConnection(conf); } /* * todo: 5.向表中插入数据 * */ public static void insertData(String tableName,String rowKey,String columnFamily,String columnName,String value) throws IOException { // 1.获取连接对象 Table table = conn.getTable(TableName.valueOf(tableName)); // 2.创建Put对象 Put put = new Put(Bytes.toBytes(rowKey)); /* * 这里如果批量插入多条数据(也就是多个rowkey),就需要创建多个put对象, * 一一对应的执行下面操作,最后将多个put对象放入一个list集合中,传入table.put()中 * */ // 3.给put对象赋值
put.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(columnName),Bytes.toBytes(value)); /* * 这里如果同一个rowkey(也就是同一条数据)有多个列,只需 要继续在这个put对象下addColumn即可 * */ // 4.插入数据 table.put(put); // 5.关闭表连接 table.close(); } public static void main(String[] args) throws Exception { // 5.插入数据 insertData("zyp:mytest","1001","lc1","name","zhangsan"); conn.close(); } }
查看数据:(两种方式)
方式一:get
/* * todo: 6.获取单行数据(get) * */ public static void getData(String tableName,String rowkey,String columnFamily,String columnName) throws IOException { // 1.获取表对象 Table table = conn.getTable(TableName.valueOf(tableName)); // 2.创建get对象 Get get = new Get(Bytes.toBytes(rowkey)); // get.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(columnName)); /* * 这里我只根据rowkey去获取所有信息 * 如果你需要查询指定列,就需要addColumn具体信息进去 * */ // 3.获取数据 Result res = table.get(get); // 4.解析result并打印 for (Cell cell : res.rawCells()) { byte[] bytes1 = CellUtil.cloneFamily(cell); byte[] bytes2 = CellUtil.cloneQualifier(cell); byte[] bytes3 = CellUtil.cloneValue(cell); System.out.println("列簇:"+Bytes.toString(bytes1)+"\t"+ "列:"+Bytes.toString(bytes2)+"\t"+ "值:"+Bytes.toString(bytes3)); } // 5.关闭表连接 table.close(); }
方式二:scan
/* * todo: 7.获取所有数据(scan) * */ public static void scan(String tableName) throws IOException { // 1.获取表连接 Table table = conn.getTable(TableName.valueOf(tableName)); // 2.构建Scan对象 Scan scan = new Scan(Bytes.toBytes("1002"),Bytes.toBytes("1003")); /* * 这里指定了rowkey,是左闭右开 * 不指定(参数为空),就是全扫描 * */ // 3.扫描表 ResultScanner resultScanner = table.getScanner(scan); // 4.解析resultScan for (Result result : resultScanner) { // 5.打印 for (Cell cell : result.rawCells()) { byte[] bytes = CellUtil.cloneRow(cell); byte[] bytes1 = CellUtil.cloneFamily(cell); byte[] bytes2 = CellUtil.cloneQualifier(cell); byte[] bytes3 = CellUtil.cloneValue(cell); System.out.println( "rowKey:"+Bytes.toString(bytes)+"\t"+ "列簇:"+Bytes.toString(bytes1)+"\t"+ "列:"+Bytes.toString(bytes2)+"\t"+ "值:"+Bytes.toString(bytes3)); } } // 6.关闭表连接 table.close(); }
删除数据:
/* * todo: 8.删除数据 * */ public static void deleteData(String tableName,String rowKey,String columnFamily,String columnName) throws IOException { // 1.获取表连接 Table table = conn.getTable(TableName.valueOf(tableName)); // 2.构建删除对象 Delete del = new Delete(Bytes.toBytes(rowKey)); // 删除指定的列 // del.addColumn(Bytes.toBytes(columnFamily),Bytes.toBytes(columnName)); // // 慎用!!!删除该行键最新的数据(最新时间戳的版本),也可以指定时间戳,此时表里会显示该rowkey的 上一个版本的数据 // // // 删除该数据的所有版本 // del.addColumns(Bytes.toBytes(columnFamily),Bytes.toBytes(columnName)); // 删除整个列簇 // del.addFamily(Bytes.toBytes(columnFamily)); // 3.执行删除操作 table.delete(del); // 4.关闭资源 table.close(); }
删除数据的API操作比较特殊,它实际也是在进行一个put操作,put一个delete标记进去。
在删除数据的API中的几种情况:
指定rowkey,删除的是所有版本;
指定rowkey和columnFamily,删除所有版本;
指定rowkey和columnFamily和一个时间戳,删除该时间戳及之前的所有版本;
指定rowkey,columnFamily和columnName,如果是addcolumn,删除最新版本数据;(传时间戳就删除该时间戳这一条数据)
指定rowkey,columnFamily和columnName,如果是addcolumns,删除指定列所有版本;(传时间戳就删除该时间戳及之前的所有版本)
本文来自博客园,作者:{理想三旬},转载请注明原文链接:{https://www.cnblogs.com/zyp0519/}