- 创建maven项目
- 依赖
<dependencies> <!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-client --> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>2.0.5</version> </dependency> </dependencies>
- 创建类HBaseDemo
- 公共信息
Configuration conf = null; Connection conn = null; // 表的管理对象 Admin admin = null; Table table = null; // 创建表的对象 TableName tableName = TableName.valueOf("666");
- 初始化信息
@Before public void init() throws IOException{ // 创建配置文件对象 conf = HBaseConfiguration.create(); // 加载zookeeper配置 conf.set("hbase.zookeeper.quorum","node02,node03,node04"); // 获取连接 conn = ConnectionFactory.createConnection(conf); // 获取对象 admin = conn.getAdmin(); // 获取数据操作对象 table = conn.getTable(tableName); }
- 创建一张表
@Test public void createTable() throws IOException{ // 定义表描述对象 TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName); // 定义列族对象 ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder("cf".getBytes()); // 添加列族信息给表 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptorBuilder.build()); if(admin.tableExists(tableName)){ //禁用表 admin.disableTable(tableName); admin.deleteTable(tableName); } //创建表 admin.createTable(tableDescriptorBuilder.build()); }
- 给表中插入一行数据
@Test public void insert() throws IOException { Put put = new Put(Bytes.toBytes("row2222")); put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("name"), Bytes.toBytes("lisi")); put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("age"), Bytes.toBytes("341")); put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("sex"), Bytes.toBytes("women")); table.put(put); }
-
查看一行row数据
/** * Hbase 可以插入十亿行 和百万列, 所以查询需要克服io,如下减少io * 查看一行row * @throws IOException */ @Test public void get() throws IOException{ Get get = new Get(Bytes.toBytes("row2222")); // 在服务端做数据过滤,挑选出符合需求的列,也就是百万列,我只要这三个,其他的不查也就不走io get.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("name")); get.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("age")); get.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("sex")); Result result = table.get(get); Cell cell1 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("name")); Cell cell2 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("age")); Cell cell3 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("sex")); String name = Bytes.toString(CellUtil.cloneValue(cell1)); String age = Bytes.toString(CellUtil.cloneValue(cell2)); String sex = Bytes.toString(CellUtil.cloneValue(cell3)); System.out.println(name); System.out.println(age); System.out.println(sex); }
- 查看所有行数据
/** * Hbase 可以插入十亿行 和百万列, 所以查询需要克服io,如下减少io * 查看所有行row, 公司一般禁止使用,相当于mysql的select * from * @throws IOException */ @Test public void scan() throws IOException{ Scan scan = new Scan(); ResultScanner scanner = table.getScanner(scan); for (Result result : scanner) { Cell cell1 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("name")); Cell cell2 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("age")); Cell cell3 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("sex")); String name = Bytes.toString(CellUtil.cloneValue(cell1)); String age = Bytes.toString(CellUtil.cloneValue(cell2)); String sex = Bytes.toString(CellUtil.cloneValue(cell3)); System.out.println(name); System.out.println(age); System.out.println(sex); } }
- 需求:
你要查询手机的通话记录,你怎么设计row_key
通话内容有: 我的手机号、 别人的手机号码、通话时间、 通话时长、通话类型
- 创建数据:
假设有10个用户,每个用户一年产生10000条记录
@Test public void insertMangerData() throws Exception{ List<Put> puts = new ArrayList<Put>(); for (int i = 0; i < 10; i++) { String myNumber = getNumber("177"); for (int j = 0; j < 10000; j++) { // 模拟数据 别人的手机号码、通话时长、通话时间、通话类型 String otherNumber = getNumber("177"); String length = String.valueOf(random.nextInt(100)); String date = getDate("2019"); String type = String.valueOf(random.nextInt(2)); // rowkey 设计为我的手机号码 + 时间戳反转(也可以将手机号码倒过来进行数据分散) String rowkey = myNumber+"_"+(Long.MAX_VALUE-sdf.parse(date).getTime()); Put put = new Put(Bytes.toBytes(rowkey)); put.addColumn(Bytes.toBytes("cf"),Bytes.toBytes("otherNumber"),Bytes.toBytes(otherNumber)); put.addColumn(Bytes.toBytes("cf"),Bytes.toBytes("length"),Bytes.toBytes(length)); put.addColumn(Bytes.toBytes("cf"),Bytes.toBytes("date"),Bytes.toBytes(date)); put.addColumn(Bytes.toBytes("cf"),Bytes.toBytes("type"),Bytes.toBytes(type)); puts.add(put); } } table.put(puts); } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); private String getDate(String s) { return s+String.format("%02d%02d%02d%02d%02d",random.nextInt(12)+1,random.nextInt(31),random.nextInt(24),random.nextInt(60),random.nextInt(60)); } Random random = new Random(); private String getNumber(String s) { return s + String.format("%08d", random.nextInt(99999999)); }
-
获取本机手机号码的所有通话记录,假设17733292236是我的手机号码
/** * 获取本机手机号码的所有通话记录 * @throws Exception */ @Test public void scanByCondition() throws Exception{ Scan scan = new Scan(); scan.setRowPrefixFilter(Bytes.toBytes("17733292236")); ResultScanner scanner = table.getScanner(scan); for (Result result : scanner) { Cell cell1 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("otherNumber")); Cell cell2 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("length")); Cell cell3 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("type")); Cell cell4 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("date")); String otherNumber = Bytes.toString(CellUtil.cloneValue(cell1)); String length = Bytes.toString(CellUtil.cloneValue(cell2)); String type = Bytes.toString(CellUtil.cloneValue(cell3)); String date = Bytes.toString(CellUtil.cloneValue(cell4)); System.out.print(otherNumber + " - "); System.out.print(length + " - "); System.out.print(type + " - "); System.out.println(date); } }
-
查询某一个用户3月份的通话记录
/** * 查询某一个用户3月份的通话记录 */ @Test public void scanByCondition2() throws Exception { Scan scan = new Scan(); String startRow = "17733292236_"+(Long.MAX_VALUE-sdf.parse("20190331000000").getTime()); String stopRow = "17733292236_"+(Long.MAX_VALUE-sdf.parse("20190301000000").getTime()); scan.withStartRow(Bytes.toBytes(startRow)); scan.withStopRow(Bytes.toBytes(stopRow)); ResultScanner rss = table.getScanner(scan); for (Result result:rss) { Cell cell1 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("otherNumber")); Cell cell2 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("length")); Cell cell3 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("type")); Cell cell4 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("date")); String otherNumber = Bytes.toString(CellUtil.cloneValue(cell1)); String length = Bytes.toString(CellUtil.cloneValue(cell2)); String type = Bytes.toString(CellUtil.cloneValue(cell3)); String date = Bytes.toString(CellUtil.cloneValue(cell4)); System.out.print(otherNumber + " - "); System.out.print(length + " - "); System.out.print(type + " - "); System.out.println(date); } }
- 根据列族中的字段来进行查询,需要使用拦截器,例如查询row手机号码为17733292236,通话类型为1的
@Test public void getType() throws IOException{ Scan scan = new Scan(); //创建过滤器集合 FilterList filters = new FilterList(FilterList.Operator.MUST_PASS_ALL); //创建过滤器 SingleColumnValueFilter filter1 = new SingleColumnValueFilter(Bytes.toBytes("cf"), Bytes.toBytes("type"), CompareOperator.EQUAL, Bytes.toBytes("1")); filters.addFilter(filter1); //前缀过滤器 PrefixFilter filter2 = new PrefixFilter(Bytes.toBytes("17733292236")); filters.addFilter(filter2); scan.setFilter(filters); ResultScanner rss = table.getScanner(scan); for (Result result:rss) { Cell cell1 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("otherNumber")); Cell cell2 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("length")); Cell cell3 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("type")); Cell cell4 = result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("date")); String otherNumber = Bytes.toString(CellUtil.cloneValue(cell1)); String length = Bytes.toString(CellUtil.cloneValue(cell2)); String type = Bytes.toString(CellUtil.cloneValue(cell3)); String date = Bytes.toString(CellUtil.cloneValue(cell4)); System.out.print(otherNumber + " - "); System.out.print(length + " - "); System.out.print(type + " - "); System.out.println(date); } }
- 删除一行数据
@Test public void delete() throws Exception{ Delete delete = new Delete("row2222".getBytes()); table.delete(delete);
- 关闭连接
@After public void destory(){ try { table.close(); } catch (IOException e) { e.printStackTrace(); } try { admin.close(); } catch (IOException e) { e.printStackTrace(); } try { conn.close(); } catch (IOException e) { e.printStackTrace(); } }
代码地址: https://gitee.com/Xiaokeworksveryhard/big-data.git