欢迎来到我的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注公众号:Java学习之道 Fork me on GitHub

HBase的java客户端测试(二)---DML操作

测试准备

【首先同步时间:】

for node in CloudDeskTop master01 master02 slave01 slave02 slave03;do ssh $node "date -s '2017-12-30 21:32:30'";done

【slave各节点启动zookeeper集群:】

cd /software/zookeeper-3.4.10/bin/ && ./zkServer.sh start && cd - && jps

【master01启动HDFS集群:】

cd /software/ && start-dfs.sh && jps

【master01启动HBase:】

cd /software/hbase-1.2.6/bin && start-hbase.sh && jps

【master02上启动HBase:】

cd /software/hbase-1.2.6/bin && hbase-daemon.sh start master && jps

如有节点启动出现故障:
单独启动master:
cd /software/hbase-1.2.6/bin && hbase-daemon.sh start master && jps
单独启动regionserver:
cd /software/hbase-1.2.6/bin && hbase-daemon.sh start regionserver && jps
通过命令终端查看:
hbase(main):009:0> status
通过web终端查看:
http://master01的IP地址:16010/

【在主机CloudDeskTop导入java客户端开发所需jar包:】HBase1.2.6-All.zip

 

测试目标: 

 运用java代码编写程序操作HBase数据库,本次测试致力于对DML语法的java客户端操作;

 

测试代码大数据学习交流QQ群:217770236 

  1 package com.mmzs.bigdata.hbase.dml;
  2 
  3 import java.io.ByteArrayInputStream;
  4 import java.io.ByteArrayOutputStream;
  5 import java.io.IOException;
  6 import java.io.ObjectInputStream;
  7 import java.io.ObjectOutputStream;
  8 import java.util.ArrayList;
  9 import java.util.Date;
 10 import java.util.HashMap;
 11 import java.util.List;
 12 import java.util.Map;
 13 import java.util.Map.Entry;
 14 import java.util.Set;
 15 
 16 import org.apache.hadoop.conf.Configuration;
 17 import org.apache.hadoop.hbase.Cell;
 18 import org.apache.hadoop.hbase.CellUtil;
 19 import org.apache.hadoop.hbase.HBaseConfiguration;
 20 import org.apache.hadoop.hbase.TableName;
 21 import org.apache.hadoop.hbase.client.Admin;
 22 import org.apache.hadoop.hbase.client.Connection;
 23 import org.apache.hadoop.hbase.client.ConnectionFactory;
 24 import org.apache.hadoop.hbase.client.Delete;
 25 import org.apache.hadoop.hbase.client.Get;
 26 import org.apache.hadoop.hbase.client.Put;
 27 import org.apache.hadoop.hbase.client.Result;
 28 import org.apache.hadoop.hbase.client.ResultScanner;
 29 import org.apache.hadoop.hbase.client.Scan;
 30 import org.apache.hadoop.hbase.client.Table;
 31 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 32 import org.apache.hadoop.hbase.filter.FilterList;
 33 import org.apache.hadoop.hbase.filter.PrefixFilter;
 34 import org.apache.hadoop.hbase.filter.RowFilter;
 35 import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
 36 import org.apache.hadoop.hbase.filter.SubstringComparator;
 37 
 38 /**
 39  * @author hadoop
 40  * 
 41  * [HTable].put|delete|get|getScanner([Scan].addColumn|setStartRow|setStopRow|setFilter([FilterList].addFilter))
 42  *
 43  */
 44 public class DMLMain {
 45     /**
 46      * 操作HBase集群的客户端
 47      */
 48     private static Admin admin;
 49     
 50     private static Connection conn;
 51     
 52     static{
 53         //创建HBase配置
 54         Configuration conf=HBaseConfiguration.create();
 55         conf.set("hbase.zookeeper.quorum", "slave01:2181,slave02:2181,slave03:2181");
 56         try {
 57             //根据HBase配置获取HBase集群连接
 58             conn=ConnectionFactory.createConnection(conf);
 59             admin=conn.getAdmin();
 60         } catch (IOException e) {
 61             e.printStackTrace();
 62         }
 63     }
 64 
 65     public static void main(String[] args) {
 66         //这种添加方式的读数据在后面查找时容易出IO异常,因为中间涉及了二进制转换
 67 //        put("mmzs:myuser","008","base","userName","ligang00");
 68 //        put("mmzs:myuser","008","base","userAge","18");
 69 //        put("mmzs:myuser","008","base","gender","woman");
 70         
 71 /*        Date d=new Date();
 72         System.out.println(d);
 73         byte[] b=getBytes(d);
 74         System.out.println(b);
 75         Object obj=getObject(b);
 76         System.out.println(obj);*/
 77     
 78         //添加数据    
 79 /*        Map<String,Map<String,Map<String,Object>>> dataMap=new HashMap<String,Map<String,Map<String,Object>>>();
 80         
 81         Map<String,Map<String,Object>> familyMap=new HashMap<String,Map<String,Object>>();
 82 //        dataMap.put("ligang+28+1.67", familyMap);
 83 //        dataMap.put("zhanghua+28+1.67", familyMap);
 84 //        dataMap.put("zhanghua+29+1.67", familyMap);
 85 //        dataMap.put("ligang+28+1.72", familyMap);
 86 //        dataMap.put("wangwu+29+1.82", familyMap);
 87         dataMap.put("001", familyMap);
 88         dataMap.put("002", familyMap);
 89         dataMap.put("003", familyMap);
 90         dataMap.put("004", familyMap);
 91         dataMap.put("005", familyMap);
 92         dataMap.put("006", familyMap);
 93         
 94         Map<String,Object> keyValMap=new HashMap<String,Object>();
 95         keyValMap.put("height", 1.68);
 96         keyValMap.put("weight", 75.5);
 97         keyValMap.put("gender", "women");
 98         keyValMap.put("username", "zhangsan");
 99         
100         familyMap.put("extra", keyValMap);
101         
102         puts("mmzs:myuser",dataMap);*/
103         
104         
105 //        delete("mmzs:myuser","005");
106 //        delete("mmzs:myuser","002","extra","username");
107 //        deletes("mmzs:myuser","001","002","003","004","005","006","007","008");
108         
109 //        get("mmzs:myuser","005");
110         
111 //        scan("mmzs:myuser");
112         
113 //        scanByCondition("mmzs:myuser");
114     }
115     
116     /**
117      * 将二进制流读到内存通过反序列化重构生成对象
118      * @param object
119      * @return
120      */
121     private static Object getObject(byte[] b){
122         ObjectInputStream ois=null;
123         try {
124             ByteArrayInputStream bais=new ByteArrayInputStream(b);
125             ois=new ObjectInputStream(bais);
126             return ois.readObject();
127         } catch (IOException e) {
128             e.printStackTrace();
129         } catch (ClassNotFoundException e) {
130             e.printStackTrace();
131         }finally{
132             try{
133                 if(null!=ois)ois.close();
134             }catch(IOException e){
135                 e.printStackTrace();
136             }
137         }
138         return null;
139     }
140     
141     /**
142      * 将对象序列化成二进制数组
143      * @param object
144      * @return
145      */
146     private static byte[] getBytes(Object object){
147         ObjectOutputStream oos=null;
148         try {
149             ByteArrayOutputStream baos=new ByteArrayOutputStream();
150             oos=new ObjectOutputStream(baos);
151             oos.writeObject(object);
152             oos.flush();
153             return baos.toByteArray();
154         } catch (IOException e) {
155             e.printStackTrace();
156         }finally{
157             try{
158                 if(null!=oos)oos.close();
159             }catch(IOException e){
160                 e.printStackTrace();
161             }
162         }
163         return null;
164     }
165     
166     /**
167      * 打印结果集
168      * @param ress
169      */
170     private static void printResult(ResultScanner rss){
171         //遍历结果集,每一个Result对应一行记录(即对应一个RowKey)
172         for(Result res:rss){
173             String rowKey=new String(res.getRow());
174             List<Cell> cellList=res.listCells();
175             for(Cell cell:cellList){
176                 //获取当前键值对所在的列族名称
177                 String familyName=new String(CellUtil.cloneFamily(cell));
178                 //获取当前键值对的键(Key)
179                 String key=new String(CellUtil.cloneQualifier(cell));
180                 //获取当前键值对的值(Value)
181                 String value=getObject(CellUtil.cloneValue(cell)).toString();
182                 
183                 System.out.println(rowKey+"\t"+familyName+"\t"+key+":"+value);
184             }
185         }
186     }
187     
188     /**
189      * 条件查询
190      * @param tabNameStr
191      * 
192      * PrefixFilter和RowFilter都是基于行键(RowKey)的过滤器
193      */
194     public static void scanByCondition(String tabNameStr){
195         TableName tabName=TableName.valueOf(tabNameStr);
196         Scan scan=new Scan();
197         
198         //前缀过滤器,行键前缀是ligang的
199         PrefixFilter prefixFilter=new PrefixFilter("ligang".getBytes());
200         
201         //子串过滤,行键中包含1.72的
202         RowFilter rowFilter=new RowFilter(CompareOp.EQUAL,new SubstringComparator("28"));
203         
204         //行键过滤器,列族 列名 比较操作 值,显示不包含满足条件的
205         SingleColumnValueFilter scvFilter=new SingleColumnValueFilter("base".getBytes(),"userName".getBytes(),CompareOp.EQUAL,new SubstringComparator("ligang"));
206         
207         //FilterList.Operator.MUST_PASS_ALL相当于and,FilterList.Operator.MUST_PASS_ONE相当于or
208         FilterList filterList=new FilterList(FilterList.Operator.MUST_PASS_ALL);
209         //添加使用的过滤器
210 //        filterList.addFilter(prefixFilter);
211 //        filterList.addFilter(rowFilter);
212         filterList.addFilter(scvFilter);
213         
214 //        scan.setFilter(prefixFilter);
215         
216         scan.setFilter(filterList);//设置过滤
217         try {
218             Table table=conn.getTable(tabName);
219             ResultScanner ress=table.getScanner(scan);
220             printResult(ress);
221         } catch (IOException e) {
222             e.printStackTrace();
223         }
224     }
225     
226     /**
227      * 查询多条记录
228      * @param tabNameStr
229      * @param rowKey
230      */
231     public static void scan(String tabNameStr){
232         TableName tabName=TableName.valueOf(tabNameStr);
233         
234         Scan scan=new Scan();
235         
236         //过滤查询结果集中的字段
237         scan.addColumn("extra".getBytes(), "height".getBytes());
238         scan.addColumn("extra".getBytes(), "weight".getBytes());
239         
240         //设置查询的起始和结束行索引(通过行键RowKey指定)
241         scan.setStartRow("002".getBytes());
242         scan.setStopRow("006".getBytes());
243         
244         try {
245             Table table=conn.getTable(tabName);
246             //查询多行返回一个结果集
247             ResultScanner rss=table.getScanner(scan);
248             //遍历结果集,每一个Result对应一行记录(即对应一个RowKey)
249             printResult(rss);
250         } catch (IOException e) {
251             e.printStackTrace();
252         }
253     }
254     
255     /**
256      * 查询单条记录
257      * @param rowKey
258      * @param tabNameStr
259      */
260     public static void get(String tabNameStr,String rowKey){
261         TableName tabName=TableName.valueOf(tabNameStr);
262         
263         Get get=new Get(rowKey.getBytes());
264         //相当于select..字段列表...from...,如果没有下面的addColumn方法调用则相当于select *...
265         get.addColumn("base".getBytes(), "height".getBytes());
266         get.addColumn("base".getBytes(), "gender".getBytes());
267         try {
268             Table table=conn.getTable(tabName);
269             Result result=table.get(get);
270             
271             //获取行键
272             String rowKeyStr=new String(result.getRow());
273             System.out.println("行键:"+rowKeyStr);
274             
275             //获取键所对应的值
276             byte[] byteName=result.getValue("base".getBytes(), "gender".getBytes());
277             String gender=getObject(byteName).toString();
278             System.out.println("gender:"+gender);
279             
280             //获取当前行中的所有键值对
281             List<Cell> cellList=result.listCells();
282             for(Cell cell:cellList){
283                 //获取当前键值对所在的列族名称
284                 String familyName=new String(CellUtil.cloneFamily(cell));
285                 //获取当前键值对的键(Key)
286                 String key=new String(CellUtil.cloneQualifier(cell));
287                 //获取当前键值对的值(Value)
288                 byte[] byteValue=CellUtil.cloneValue(cell);
289                 String value=getObject(byteValue).toString();
290                 
291                 System.out.println(rowKey+"\t"+familyName+"\t"+key+":"+value);
292             }
293         } catch (IOException e) {
294             e.printStackTrace();
295         }
296     }
297     
298     /**
299      * 批量删除多行
300      * @param tabNameStr
301      * @param rowKey
302      */
303     public static void deletes(String tabNameStr,String... rowKeys){
304         if(rowKeys.length==0)return;
305         TableName tabName=TableName.valueOf(tabNameStr);
306         
307         List<Delete> deleteList=new ArrayList<Delete>();
308         for(String rowKey:rowKeys)deleteList.add(new Delete(rowKey.getBytes()));
309         
310         try {
311             Table table=conn.getTable(tabName);
312             table.delete(deleteList);
313             System.out.println("删除完成!");
314         } catch (IOException e) {
315             e.printStackTrace();
316         }
317     }
318     
319     /**
320      * 删除行中的键值对
321      * @param tabNameStr
322      * @param rowKey
323      * @param key
324      */
325     public static void delete(String tabNameStr,String rowKey,String family,String key){
326         TableName tabName=TableName.valueOf(tabNameStr);
327         try {
328             Table table=conn.getTable(tabName);
329             Delete delete=new Delete(rowKey.getBytes());
330             delete.addColumn(family.getBytes(), key.getBytes());
331             table.delete(delete);
332             System.out.println("删除完成!");
333         } catch (IOException e) {
334             e.printStackTrace();
335         }
336     }
337     
338     /**
339      * 删除整行
340      * @param tabNameStr
341      * @param rowKey
342      */
343     public static void delete(String tabNameStr,String rowKey){
344         TableName tabName=TableName.valueOf(tabNameStr);
345         try {
346             Table table=conn.getTable(tabName);
347             Delete delete=new Delete(rowKey.getBytes());
348             table.delete(delete);
349             System.out.println("删除完成!");
350         } catch (IOException e) {
351             e.printStackTrace();
352         }
353     }
354     
355     /**
356      * 增加或修改数据(表名、行键、列族、列、值)
357      */
358     public static void put(String tabNameStr,String rowKey,String family,String key,String value){
359         TableName tabName=TableName.valueOf(tabNameStr);
360         try {
361             Table table=conn.getTable(tabName);
362             Put put=new Put(rowKey.getBytes());
363             put.addColumn(family.getBytes(), key.getBytes(), value.getBytes());
364             table.put(put);
365             System.out.println("操作完成!");
366         } catch (IOException e) {
367             e.printStackTrace();
368         }
369     }
370     
371     /**
372      * 批量插入或修改数据
373      * @param tabNameStr
374      * @param dataMap
375      */
376     public static void puts(String tabNameStr,Map<String,Map<String,Map<String,Object>>> dataMap){
377         List<Put> putList=new ArrayList<Put>();
378         Set<Entry<String, Map<String, Map<String, Object>>>> entrys=dataMap.entrySet();
379         for(Entry<String, Map<String, Map<String, Object>>> entry:entrys){
380             //获取行的rowKey
381             byte[] rowKey=entry.getKey().getBytes();
382             Put put=new Put(rowKey);
383             putList.add(put);
384             //获取行的所有列族
385             Map<String, Map<String, Object>> familyMap=entry.getValue();
386             Set<Entry<String, Map<String, Object>>> familyEntrys=familyMap.entrySet();
387             for(Entry<String, Map<String, Object>> familyEntry:familyEntrys){
388                 //获取列族名称
389                 byte[] familyName=familyEntry.getKey().getBytes();
390                 //获取列族下左右的键值对
391                 Map<String, Object> keyVals=familyEntry.getValue();
392                 Set<Entry<String, Object>> keyValEntrys=keyVals.entrySet();
393                 for(Entry<String, Object> keyValEntry:keyValEntrys){
394                     byte[] key=keyValEntry.getKey().getBytes();
395                     byte[] value=getBytes(keyValEntry.getValue());
396                     put.addColumn(familyName, key, value);
397                 }
398             }
399         }
400         
401         TableName tabName=TableName.valueOf(tabNameStr);
402         try {
403             Table table=conn.getTable(tabName);
404             table.put(putList);
405             System.out.println("操作完成!");
406         } catch (IOException e) {
407             e.printStackTrace();
408         }
409     }
410 }
DMLMain

 

测试结果:

  在命令端查看,查看方式,可参考:http://www.cnblogs.com/mmzs/p/8135327.html

 

测试小结:

  HBase是分布式的、可扩展的、且基于Hadop的大数据NOSQL存储数据库(号称十亿行、百万列),该数据库的每一行也是保存一条记录,但是与关系数据库不同的是,该数据库无需事先定义字段和表结构,只需要指定表名和列族;每一行由指定的一到多个族组成,每个族上可以保存若干个键值对(每一行的每个族上的键值对数量可以是任意的),即每一行的单元格数量不一定相等,每一个单元格中保存同一个键名但不同版本值的若干个键值对(即同一个字段名中有不同版本的字段值),当需要查询某一个字段值时需要指定的坐标是:
  表名(table name)—>行健(row key)—>列族(column family)—>字段名(column name)—>版本号(version code)

 

 

posted @ 2017-12-31 10:23  淼淼之森  阅读(603)  评论(0编辑  收藏  举报
  👉转载请注明出处和署名