HBase Java-API

环境准备

    1.启动hadoop\zookeeper\hbase三大组件

    2.在eclipse中新建一个普通的java工程

    3.将hbase安装目录下lib目录中jar包复制到工程中,并添加到build-path中

基本操作

package com.jv.hbase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.junit.Before;
import org.junit.Test;

public class TestHBase {
	Configuration conf;
	@Before
	public void init() {
		conf = HBaseConfiguration.create();
		conf.set("hbase.zookeeper.quorum","192.168.245.141:2181,192.168.245.142:2181,192.168.245.143:2181");
	}
	//删除表
	@Test
	public void deleteTable() throws Exception {
		HBaseAdmin admin = new HBaseAdmin(conf);
		
		//先要disable表才可以
		admin.disableTable("acct".getBytes());
		admin.deleteTable("acct".getBytes());
		//4.关闭连接
		admin.close();
	}
	
	//删除数据
	@Test
	public void delete() throws Exception {
		HTable tab = new HTable(conf,"acct".getBytes());
		Delete delete = new Delete("rk1".getBytes());
		tab.delete(delete);
	}
	
	//查询数据
	@Test
	public void get() throws Exception {
		HTable tab = new HTable(conf,"acct".getBytes());
		Get get = new Get("rk1".getBytes());
		get.addColumn("fam1".getBytes(), "c1".getBytes());
		Result rlt = tab.get(get);
		System.out.println(new String(rlt.getValue("fam1".getBytes(), "c1".getBytes())));
	}
	
	//插入和更新数据
	@Test
	public void put() throws Exception {
		HTable tab = new HTable(conf,"acct".getBytes());
		Put put = new Put("rk1".getBytes());
		put.add("fam1".getBytes(), "c1".getBytes(), "Messi".getBytes());
		tab.put(put);
	}
	
	@Test
	public void create() throws Exception {
		HBaseAdmin admin = new HBaseAdmin(conf);

		//表的描述器,声明表名
		HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("acct"));
		//声明列族
		HColumnDescriptor hcd_fam1 = new HColumnDescriptor("fam1");
		//设置cell的最大版本数
		hcd_fam1.setMaxVersions(3);
		//声明列族
		HColumnDescriptor hcd_fam2 = new HColumnDescriptor("fam2");
		//将列族绑定到表上
		htd.addFamily(hcd_fam1);
		htd.addFamily(hcd_fam2);
		//执行表创建操作
		admin.createTable(htd);
		//关闭连接
		admin.close();
	}
	
}

如果要想把日志打印到控制台,需要log4j.properties放到源文件夹下,内容为

log4j.rootLogger=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

    上面的使用其实不是很方便,可以将上面的api才做一次封装,比如所有的接收byte[]的全部封装为String,表添加列族更加搞一个可变参数方法,删除表的disable操作隐藏起来等等。因为一般一个表都只设计一个列族,所以在这种情况下,完全可以指定一个默认列族,然后将列暴露出来供开发人员操作。

    对于没有使用Phoenix的公司可以按照上面建议去封装,后面会介绍Phoenix,它将hbase的api封装为了jdbc接口那套规范使用起来很方便,不过它和hbase使强相关的。

复杂查询(scan的使用)

package com.jv.hbase;

import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.ColumnPrefixFilter;
import org.apache.hadoop.hbase.filter.ColumnRangeFilter;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.FilterList.Operator;
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
import org.apache.hadoop.hbase.filter.RegexStringComparator;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;


public class TestScan {
	Logger logger = Logger.getLogger(TestScan.class);
	Configuration conf;
	@Before
	public void init() {
		conf = HBaseConfiguration.create();
		conf.set("hbase.zookeeper.quorum","192.168.245.141:2181,192.168.245.142:2181,192.168.245.143:2181");
	}
	
	@Test
	public void initData() throws Exception {
		//删除数据
		HTable tab = new HTable(conf,"acct".getBytes());
		Delete delete = new Delete("rk1".getBytes());
		tab.delete(delete);
		
		//插入数据
		Put put = new Put("rk1".getBytes());
		put.add("fam1".getBytes(), "name".getBytes(), "Messi".getBytes());
		put.add("fam1".getBytes(), "age".getBytes(), "30".getBytes());
		put.add("fam1".getBytes(), "salary".getBytes(), "1024".getBytes());
		tab.put(put);
		
		put = new Put("rk2".getBytes());
		put.add("fam1".getBytes(), "name".getBytes(), "HaVi".getBytes());
		put.add("fam1".getBytes(), "age".getBytes(), "34".getBytes());
		put.add("fam1".getBytes(), "salary".getBytes(), "512".getBytes());
		tab.put(put);
		
		put = new Put("rk3".getBytes());
		put.add("fam1".getBytes(), "name".getBytes(), "Ibrahimović".getBytes());
		put.add("fam1".getBytes(), "age".getBytes(), "35".getBytes());
		put.add("fam1".getBytes(), "salary".getBytes(), "1536".getBytes());
		tab.put(put);
		
		put = new Put("rk4".getBytes());
		put.add("fam1".getBytes(), "name".getBytes(), "Iniesta".getBytes());
		put.add("fam1".getBytes(), "age".getBytes(), "33".getBytes());
		put.add("fam1".getBytes(), "salary".getBytes(), "1314".getBytes());
		put.add("fam1".getBytes(), "aa".getBytes(), "testaa".getBytes());
		put.add("fam1".getBytes(), "ba".getBytes(), "testba".getBytes());
		tab.put(put);
	}
	
	//设置条件扫描范围
	@Test
	public void scan1() throws Exception{
		//1.创建HTable对象
		HTable tab = new HTable(conf, "acct".getBytes());
		//2.创建扫描器
		//--如果不设置 则扫描 全表数据
		Scan scan = new Scan();
		//--设置条件扫描范围数据
		scan.setStartRow("rk2".getBytes());
		scan.setStopRow("rk4".getBytes());
		//3.执行扫描得到结果
		ResultScanner rs = tab.getScanner(scan);
		
		//4.遍历结果
		printResult(rs);
		
		//5.关闭资源
		tab.close();
	}
	
	//设置行过滤器
	@Test
	public void scan2() throws Exception{
		//1.创建HTable对象
		HTable tab = new HTable(conf, "acct".getBytes());
		//2.创建扫描器
		//--如果不设置 则扫描 全表数据
		Scan scan = new Scan();
		
		//设置过滤器,记住这步一定要放在getScanner之前
		//Filter filter = new RowFilter(CompareOp.NOT_EQUAL, new BinaryComparator("rk3".getBytes()));
		//Filter filter = new RowFilter(CompareOp.EQUAL, new RegexStringComparator("^.*4.*$"));//使用正则的强大匹配功能,找行键里面包含字母4的行
		//Filter filter = new KeyOnlyFilter();//输出结果只有key没有value
		//Filter filter = new RandomRowFilter(0.5f);//每行记录有50%的记录被选中输出,可以用来抽样
		//Filter filter = new InclusiveStopFilter("rk2".getBytes());//输出结果只包含rk2及其之前的行
		Filter filter = new FirstKeyOnlyFilter();//输出排在第一的列对应的key-value,排序是按照字符串自然排序的
		//Filter filter = new ColumnPrefixFilter("c3".getBytes());
		scan.setFilter(filter);
		
		//3.执行扫描得到结果
		ResultScanner rs = tab.getScanner(scan);
		
		//4.遍历结果
		printResult(rs);
		
		//5.关闭资源
		tab.close();
	}

	//设置列过滤器
	@Test
	public void scan3() throws Exception{
		//1.创建HTable对象
		HTable tab = new HTable(conf, "acct".getBytes());
		//2.创建扫描器
		//--如果不设置 则扫描 全表数据
		Scan scan = new Scan();
		
		//设置过滤器,记住这步一定要放在getScanner之前
		//Filter filter = new ColumnPrefixFilter("a".getBytes());//输出列明第一个字母是"a"的列对应的key-value
		//Filter filter = new ColumnCountGetFilter(10);//输出所有行的前10列
		/*
		 * 最大最小是按照字符串自然排序的
		 * minColumn:最小的列名
		 * minColumnInclusive:是否包含该列
		 * maxColumn:最大的列名
		 * maxColumnInclusive:是否包含该列
		 */
		Filter filter = new ColumnRangeFilter("age".getBytes(),true,"salary".getBytes(),true);
		scan.setFilter(filter);
		
		//3.执行扫描得到结果
		ResultScanner rs = tab.getScanner(scan);
		
		//4.遍历结果
		printResult(rs);
		
		//5.关闭资源
		tab.close();
	}
	
	//设置过滤器列表,功能像spring中的拦截器栈
	@Test
	public void scan4() throws Exception{
		//1.创建HTable对象
		HTable tab = new HTable(conf, "acct".getBytes());
		//2.创建扫描器
		//--如果不设置 则扫描 全表数据
		Scan scan = new Scan();
		/*
		 * 组合的结果是:行键包含数字4,列名以a打头列对应的key-value
		 */
		Filter filter1 = new RowFilter(CompareOp.EQUAL, new RegexStringComparator("^.*4.*$"));
		Filter filter2 = new ColumnPrefixFilter("a".getBytes());
		//FilterList fl1 = new FilterList(Operator.MUST_PASS_ONE, filter1,filter2);//只要一个符合就代表成功,相当于"或"
		FilterList fl2 = new FilterList(Operator.MUST_PASS_ALL, filter1,filter2);//必须所有的条件都符合才算成功,相当于"与"
		scan.setFilter(fl2);
		
		//3.执行扫描得到结果
		ResultScanner rs = tab.getScanner(scan);
		
		//4.遍历结果
		printResult(rs);
		
		//5.关闭资源
		tab.close();
	}
	
	private void printResult(ResultScanner rs) {
		Iterator<Result> it = rs.iterator();
		while(it.hasNext()){
			Result r = it.next();
			//--获取行键
			String rk = new String(r.getRow());
			NavigableMap<byte[],NavigableMap<byte[],NavigableMap<Long,byte[]>>> map = r.getMap();
			for(Map.Entry<byte[],NavigableMap<byte[],NavigableMap<Long,byte[]>>> entry: map.entrySet()){
				String cf = new String(entry.getKey());
				NavigableMap<byte[],NavigableMap<Long,byte[]>> cMap = entry.getValue();
				for(Map.Entry<byte[],NavigableMap<Long,byte[]>> entry2 : cMap.entrySet()){
					String c = new String(entry2.getKey());
					NavigableMap<Long, byte[]> value = entry2.getValue();
					String v = new String(value.firstEntry().getValue());
					logger.info("--rk:"+rk+"--cf:"+cf+"--c:"+c+"--v:"+v);
				}
			}
		}
	}
}

猜你喜欢

转载自my.oschina.net/u/3049601/blog/1821262