spring hbase template延续spring 模板模式的一贯风格,只需要配置连接池属性和注册template,重写template的方法即可使用。
吐槽:个人当时网上搜索时,发现很多都是copy代码,用不了。无语。
开始之前:有一个可用的maven web工程,下载hbase client 和spring hadoop,spring hbase相关jar.
org.apache.hbase
hbase-client
1.2.1
jdk.tools
jdk.tools
com.google.guava
guava
jdk.tools
jdk.tools
1.8
system
${JAVA_HOME}/lib/tools.jar
org.apache.hadoop
hadoop-hdfs
2.5.1
org.springframework.data
spring-data-hadoop
2.4.0.RELEASE
org.springframework.data
spring-data-hadoop-core
2.4.0.RELEASE
org.apache.hbase
hbase
1.2.1
pom
下面一一贴代码并解释:
一、配置template bean对象,并且设置hbase连接属性。
具体方法:在配置spring xml文件夹中建立spring-hbase.xml
说明:
1、hdp:configuration指定hadoop(hdfs)使用那个配置(可以直接指定,也可是是单独的文件)作为连接信息。
2、 这句表明hbase的配置直接使用hadoop的配置。
3、注册hbaseTemplate bean。配置引用为2里的配置。
然后在相同文件夹下新建spring-hbase.xml(haddop config)所需的连接信文件hbase-site.xml.(这个文件便是hbase安装目录里的同名文件,根据自己的需求修改即可)
hbase.rootdir
hdfs://192.168.1.2:9000/hbase
hbase.cluster.distributed
true
hbase.master.port
16000
hbase.master.info.port
60010
hbase.zookeeper.quorum
192.168.1.2,192.168.1.3
hbase.zookeeper.property.dataDir
/usr/zookeeper/data
hbase.zookeeper.property.clientPort
2181
fs.hdfs.impl
org.apache.hadoop.hdfs.DistributedFileSystem
上面的文件定义了连接的hdfs入口(hbase配置hdfs所使用的路径,需要手动建立hdfs路径。端口为hdfs访问端口,不修改为默认9000),分布式类型(单点false,伪分布式和分布式均为true),主节点端口(默认16000),页面访问端口(默认60010),zookeper集群、端口、数据文件存放位置。
配置中机器使用ip还是机器名需要根据hbase的安装配置。如果配置机器名,就使用机器名;否则,使用IP即可。不过,使用机器名时,需要在本地添加host认证。(具体问百度)
tips: 如果是伪分布式,去掉zookeper data文件配置,将主机设为单点地址(hbase安装机器ip或机器名),端口默认(或按hbase安装配置)。
二、配置完文件后(记得spring 扫描spring-hbase.xml),编写template调用工具类。
为了增加通用性,我自己增加两个实体类作为辅助对象。
1、HQuery hbase查询时所使用对象,主要申明查询的startrow,endrow,scan,filter等。以下为片段
@Component
public class HQuery {
private String table;
private String family;
private String qualifier;
private String qualifierValue;
private String row;
private String startRow;
private String stopRow;
private Filter filter;
private PageFilter pageFilter;
private Scan scan;
private List columns = Lists.newArrayList();
2、HBaseColumn 数据多字段写入时的辅助实体。family,字段名和值
public class HBaseColumn {
private String family;
private String qualifier;
private String value;
3、HBaseTemplate 工具类。
@Repository
public class HBaseTemplate {
private final Logger logger = Logger.getLogger(this.getClass());
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "spring-hbase.xml" });
// BeanFactory factory = (BeanFactory) context;
HbaseTemplate htemplate = (HbaseTemplate) context.getBean("hbaseTemplate");
/**
* 写数据
*
* @param tableName
* @param action
* @return
*/
public Object execute(HQuery query) {
if(StringUtils.isBlank(query.getRow()) || query.getColumns().isEmpty()){
return null;
}
return htemplate.execute(query.getTable(), new TableCallback() {
@SuppressWarnings("deprecation")
@Override
public Object doInTable(HTableInterface table) throws Throwable {
try {
byte[] rowkey = query.getRow().getBytes();
Put put = new Put(rowkey);
for(HBaseColumn col:query.getColumns()){
put.addColumn(Bytes.toBytes(col.getFamily()), Bytes.toBytes(col.getQualifier()),
Bytes.toBytes(col.getValue()));
}
table.put(put);
} catch (Exception e) {
logger.warn("==> hbase get object fail> "+query.getRow());
}
return null;
}
});
}
/**
* 通过表名和key获取一行数据
*
* @param tableName
* @param rowName
* @return
*/
public T get(HQuery query, Class c) {
if(StringUtils.isBlank(query.getTable()) || StringUtils.isBlank(query.getRow())){
return null;
}
return htemplate.get(query.getTable(), query.getRow(), new RowMapper() {
public T mapRow(Result result, int rowNum) throws Exception {
List ceList = result.listCells();
T item=c.newInstance();
JSONObject obj = new JSONObject();
if (ceList != null && ceList.size() > 0) {
for (Cell cell : ceList) {
obj.put(Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
cell.getQualifierLength()),
Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
}
}else{
return null;
}
item=JSON.parseObject(obj.toJSONString(), c);
return item;
}
});
}
/**
* 通过表名 key 和 列族 和列 获取一个数据
*
* @param tableName
* @param rowName
* @param familyName
* @param qualifier
* @return
*/
public String getColumn(HQuery query) {
if(StringUtils.isBlank(query.getTable()) || StringUtils.isBlank(query.getRow())
|| StringUtils.isBlank(query.getFamily()) || StringUtils.isBlank(query.getQualifier())){
return null;
}
return htemplate.get(query.getTable(), query.getRow(), query.getFamily(), query.getQualifier(), new RowMapper() {
public String mapRow(Result result, int rowNum) throws Exception {
List ceList = result.listCells();
String res = "";
if (ceList != null && ceList.size() > 0) {
for (Cell cell : ceList) {
res = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
}
}
return res;
}
});
}
/**
* 通过表名,开始行键和结束行键获取数据
*
* @param HQuery
* @return
*/
public List find(HQuery query,Class c) {
//如果未设置scan,设置scan
if (query.getScan() == null) {
//起止搜索
if(StringUtils.isNotBlank(query.getStartRow()) && StringUtils.isNotBlank(query.getStopRow())){
query.setSearchLimit(query.getStartRow(), query.getStopRow());
}
//主要配合pageFilter,指定起始点
if(StringUtils.isNotBlank(query.getStartRow())){
query.setScanStartRow(query.getStartRow());
}
//列匹配搜索
if(StringUtils.isNotBlank(query.getFamily()) &&StringUtils.isNotBlank(query.getQualifier())
&&StringUtils.isNotBlank(query.getQualifierValue())){
query.setSearchEqualFilter(query.getFamily(),query.getQualifier(),query.getQualifierValue());
}
//分页搜索
if(query.getPageFilter()!=null){
query.setFilters(query.getPageFilter());
}
if(query.getScan()==null){
query.setScan(new Scan());
}
}
//设置缓存
query.getScan().setCacheBlocks(false);
query.getScan().setCaching(2000);
return htemplate.find(query.getTable(), query.getScan(), new RowMapper() {
@Override
public T mapRow(Result result, int rowNum) throws Exception {
List ceList = result.listCells();
JSONObject obj = new JSONObject();
T item =c.newInstance();
if (ceList != null && ceList.size() > 0) {
for (Cell cell : ceList) {
// String row = Bytes.toString(cell.getRowArray(),
// cell.getRowOffset(), cell.getRowLength());
// String family = Bytes.toString(cell.getFamilyArray(),
// cell.getFamilyOffset(),
// cell.getFamilyLength());
String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(),
cell.getValueLength());
String quali = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
cell.getQualifierLength());
if(value.startsWith("[")){
obj.put(quali, JSONArray.parseArray(value));
}else{
obj.put(quali, value);
}
}
}
item =JSON.parseObject(obj.toJSONString(), c);
return item;
}
});
}
public void delete(HQuery query){
htemplate.delete(query.getTable(), query.getRow(), query.getFamily());
}
} | | |
以上几个方法均是hbaseTemplate的方法扩展,个人只需要实现回调方法逻辑处理内容(callback或rowmapper)即可。
为了增加查询效率。在scan中设置了缓存。
query.getScan().setCacheBlocks(false); query.getScan().setCaching(2000);
以上,均为个人实际代码。转载请注明出处。----------------------------------