环境准备
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);
}
}
}
}
}