【14笔记】HBase实战--微博案例
生活随笔
收集整理的這篇文章主要介紹了
【14笔记】HBase实战--微博案例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、需求分析
1、微博內容的瀏覽,數據庫表設計
2、用戶社交體現:關注用戶,取關用戶
3、拉取關注的人的微博內容
2、代碼設計
1)創建命名空間以及表名的定義
2)創建微博內容表
3)創建用戶關系表
4)創建用戶微博內容接收郵件表
5)發布微博內容
6)添加關注用戶
7)移除(取關)用戶
8)獲取關注的人的微博內容
9)測試
1)創建命名空間以及表名的定義
//獲取配置conf private Configuration conf = HBaseConfiguration.create();//微博內容表的表名 private static final byte[] TABLE_CONTENT = Bytes.toBytes("weibo:content"); //用戶關系表的表名 private static final byte[] TABLE_RELATIONS = Bytes.toBytes("weibo:relations"); //微博收件箱表的表名 private static final byte[] TABLE_RECEIVE_CONTENT_EMAIL = Bytes.toBytes("weibo:receive_content_email"); public void initNamespace(){HBaseAdmin admin = null;try {admin = new HBaseAdmin(conf);//命名空間類似于關系型數據庫中的schema,可以想象成文件夾NamespaceDescriptor weibo = NamespaceDescriptor.create("weibo").addConfiguration("creator", "Jinji").addConfiguration("create_time", System.currentTimeMillis() + "").build();admin.createNamespace(weibo);} catch (MasterNotRunningException e) {e.printStackTrace();} catch (ZooKeeperConnectionException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{if(null != admin){try {admin.close();} catch (IOException e) {e.printStackTrace();}}} }2)創建微博內容表
表結構:
| Table Name | weibo:content |
| RowKey | 用戶ID_時間戳 |
| ColumnFamily | info |
| ColumnLabel | 標題,內容,圖片 |
| Version | 1個版本 |
3)創建用戶關系表
表結構:
| Table | Name weibo:relations |
| RowKey | 用戶ID |
| ColumnFamily | attends、fans |
| ColumnLabel | 關注用戶ID,粉絲用戶ID |
| ColumnValue | 用戶ID |
| Version | 1個版本 |
4)創建微博收件箱表
表結構:
| Table Name | weibo:receive_content_email |
| RowKey | 用戶ID |
| ColumnFamily | info |
| ColumnLabel | 用戶ID |
| ColumnValue | 取微博內容的RowKey |
| Version | 1000 |
5)發布微博內容
/*** 微博內容*/ public class Message {private String uid;private String timestamp;private String content;public String getUid() {return uid;}public void setUid(String uid) {this.uid = uid;}public String getTimestamp() {return timestamp;}public void setTimestamp(String timestamp) {this.timestamp = timestamp;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "Message [uid=" + uid + ", timestamp=" + timestamp + ", content=" + content + "]";} } /*** 發布微博* a、微博內容表中數據+1* b、向微博收件箱表中加入微博的Rowkey*/ public void publishContent(String uid, String content){HConnection connection = null;try {connection = HConnectionManager.createConnection(conf);//a、微博內容表中添加1條數據,首先獲取微博內容表描述HTableInterface contentTBL = connection.getTable(TableName.valueOf(TABLE_CONTENT));//組裝Rowkeylong timestamp = System.currentTimeMillis();String rowKey = uid + "_" + timestamp;Put put = new Put(Bytes.toBytes(rowKey));put.add(Bytes.toBytes("info"), Bytes.toBytes("content"), timestamp, Bytes.toBytes(content));contentTBL.put(put);//b、向微博收件箱表中加入發布的Rowkey//b.1、查詢用戶關系表,得到當前用戶有哪些粉絲HTableInterface relationsTBL = connection.getTable(TableName.valueOf(TABLE_RELATIONS));//b.2、取出目標數據Get get = new Get(Bytes.toBytes(uid));get.addFamily(Bytes.toBytes("fans"));Result result = relationsTBL.get(get);List<byte[]> fans = new ArrayList<byte[]>();//遍歷取出當前發布微博的用戶的所有粉絲數據for(Cell cell : result.rawCells()){fans.add(CellUtil.cloneQualifier(cell));}//如果該用戶沒有粉絲,則直接returnif(fans.size() <= 0) return;//開始操作收件箱表HTableInterface recTBL = connection.getTable(TableName.valueOf(TABLE_RECEIVE_CONTENT_EMAIL));List<Put> puts = new ArrayList<Put>();for(byte[] fan : fans){Put fanPut = new Put(fan);fanPut.add(Bytes.toBytes("info"), Bytes.toBytes(uid), timestamp, Bytes.toBytes(rowKey));puts.add(fanPut);}recTBL.put(puts);} catch (IOException e) {e.printStackTrace();}finally{if(null != connection){try {connection.close();} catch (IOException e) {e.printStackTrace();}}} }6)添加關注用戶
/*** 關注用戶邏輯* a、在微博用戶關系表中,對當前主動操作的用戶添加新的關注的好友* b、在微博用戶關系表中,對被關注的用戶添加粉絲(當前操作的用戶)* c、當前操作用戶的微博收件箱添加所關注的用戶發布的微博rowkey*/ public void addAttends(String uid, String... attends){//參數過濾if(attends == null || attends.length <= 0 || uid == null || uid.length() <= 0){return;}HConnection connection = null;try {connection = HConnectionManager.createConnection(conf);//用戶關系表操作對象(連接到用戶關系表)HTableInterface relationsTBL = connection.getTable(TableName.valueOf(TABLE_RELATIONS));List<Put> puts = new ArrayList<Put>();//a、在微博用戶關系表中,添加新關注的好友Put attendPut = new Put(Bytes.toBytes(uid));for(String attend : attends){//為當前用戶添加關注的人attendPut.add(Bytes.toBytes("attends"), Bytes.toBytes(attend), Bytes.toBytes(attend));//b、為被關注的人,添加粉絲Put fansPut = new Put(Bytes.toBytes(attend));fansPut.add(Bytes.toBytes("fans"), Bytes.toBytes(uid), Bytes.toBytes(uid));//將所有關注的人一個一個的添加到puts(List)集合中puts.add(fansPut);}puts.add(attendPut);relationsTBL.put(puts);//c.1、微博收件箱添加關注的用戶發布的微博內容(content)的rowkeyHTableInterface contentTBL = connection.getTable(TableName.valueOf(TABLE_CONTENT));Scan scan = new Scan();//用于存放取出來的關注的人所發布的微博的rowkeyList<byte[]> rowkeys = new ArrayList<byte[]>();for(String attend : attends){//過濾掃描rowkey,即:前置位匹配被關注的人的uid_RowFilter filter = new RowFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator(attend + "_"));//為掃描對象指定過濾規則scan.setFilter(filter);//通過掃描對象得到scannerResultScanner result = contentTBL.getScanner(scan);//迭代器遍歷掃描出來的結果集Iterator<Result> iterator = result.iterator();while(iterator.hasNext()){//取出每一個符合掃描結果的那一行數據Result r = iterator.next();for(Cell cell : r.rawCells()){//將得到的rowkey放置于集合容器中rowkeys.add(CellUtil.cloneRow(cell));}}}//c.2、將取出的微博rowkey放置于當前操作用戶的收件箱中if(rowkeys.size() <= 0) return;//得到微博收件箱表的操作對象HTableInterface recTBL = connection.getTable(TableName.valueOf(TABLE_RECEIVE_CONTENT_EMAIL));//用于存放多個關注的用戶的發布的多條微博rowkey信息List<Put> recPuts = new ArrayList<Put>();for(byte[] rk : rowkeys){Put put = new Put(Bytes.toBytes(uid));//uid_timestampString rowKey = Bytes.toString(rk);//借取uidString attendUID = rowKey.substring(0, rowKey.indexOf("_"));long timestamp = Long.parseLong(rowKey.substring(rowKey.indexOf("_") + 1));//將微博rowkey添加到指定單元格中put.add(Bytes.toBytes("info"), Bytes.toBytes(attendUID), timestamp, rk);recPuts.add(put);}recTBL.put(recPuts);} catch (IOException e) {e.printStackTrace();}finally{if(null != connection){try {connection.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}} }7)移除(取關)用戶
/*** 取消關注(remove)* a、在微博用戶關系表中,對當前主動操作的用戶刪除對應取關的好友* b、在微博用戶關系表中,對被取消關注的人刪除粉絲(當前操作人)* c、從收件箱中,刪除取關的人的微博的rowkey*/ public void removeAttends(String uid, String... attends){//過濾數據if(uid == null || uid.length() <= 0 || attends == null || attends.length <= 0) return;HConnection connection = null;try {connection = HConnectionManager.createConnection(conf);//a、在微博用戶關系表中,刪除已關注的好友HTableInterface relationsTBL = connection.getTable(TableName.valueOf(TABLE_RELATIONS));//待刪除的用戶關系表中的所有數據List<Delete> deletes = new ArrayList<Delete>();//當前取關操作者的uid對應的Delete對象Delete attendDelete = new Delete(Bytes.toBytes(uid));//遍歷取關,同時每次取關都要將被取關的人的粉絲-1for(String attend : attends){attendDelete.deleteColumn(Bytes.toBytes("attends"), Bytes.toBytes(attend));//bDelete fansDelete = new Delete(Bytes.toBytes(attend));fansDelete.deleteColumn(Bytes.toBytes("fans"), Bytes.toBytes(uid));deletes.add(fansDelete);}deletes.add(attendDelete);relationsTBL.delete(deletes);//c、刪除取關的人的微博rowkey 從 收件箱表中HTableInterface recTBL = connection.getTable(TableName.valueOf(TABLE_RECEIVE_CONTENT_EMAIL));Delete recDelete = new Delete(Bytes.toBytes(uid));for(String attend : attends){recDelete.deleteColumn(Bytes.toBytes("info"), Bytes.toBytes(attend));}recTBL.delete(recDelete);} catch (IOException e) {e.printStackTrace();} }8)獲取關注的人的微博內容
/*** 獲取微博實際內容* a、從微博收件箱中獲取所有關注的人的發布的微博的rowkey* b、根據得到的rowkey去微博內容表中得到數據* c、將得到的數據封裝到Message對象中*/ public List<Message> getAttendsContent(String uid){HConnection connection = null;try {connection = HConnectionManager.createConnection(conf);HTableInterface recTBL = connection.getTable(TableName.valueOf(TABLE_RECEIVE_CONTENT_EMAIL));//a、從收件箱中取得微博rowKeyGet get = new Get(Bytes.toBytes(uid));//設置最大版本號get.setMaxVersions(5);List<byte[]> rowkeys = new ArrayList<byte[]>();Result result = recTBL.get(get);for(Cell cell : result.rawCells()){rowkeys.add(CellUtil.cloneValue(cell));}//b、根據取出的所有rowkey去微博內容表中檢索數據HTableInterface contentTBL = connection.getTable(TableName.valueOf(TABLE_CONTENT));List<Get> gets = new ArrayList<Get>();//根據rowkey取出對應微博的具體內容for(byte[] rk : rowkeys){Get g = new Get(rk);gets.add(g);}//得到所有的微博內容的result對象Result[] results = contentTBL.get(gets);List<Message> messages = new ArrayList<Message>();for(Result res : results){for(Cell cell : res.rawCells()){Message message = new Message();String rowKey = Bytes.toString(CellUtil.cloneRow(cell));String userid = rowKey.substring(0, rowKey.indexOf("_"));String timestamp = rowKey.substring(rowKey.indexOf("_") + 1);String content = Bytes.toString(CellUtil.cloneValue(cell));message.setContent(content);message.setTimestamp(timestamp);message.setUid(userid);messages.add(message);}}return messages;} catch (IOException e) {e.printStackTrace();}finally{try {connection.close();} catch (IOException e) {e.printStackTrace();}}return null; }9)測試
/*** 測試發布微博內容*/ public void testPublishContent(WeiBo wb){wb.publishContent("0001", "今天買了一包空氣,送了點薯片,非常開心!!");wb.publishContent("0001", "今天天氣不錯。"); }/*** 測試添加關注*/ public void testAddAttend(WeiBo wb){wb.publishContent("0008", "準備下課!");wb.publishContent("0009", "準備關機!");wb.addAttends("0001", "0008", "0009"); }/*** 測試取消關注*/ public void testRemoveAttend(WeiBo wb){wb.removeAttends("0001", "0008"); }/*** 測試展示內容*/ public void testShowMessage(WeiBo wb){List<Message> messages = wb.getAttendsContent("0001");for(Message message : messages){System.out.println(message);} }public static void main(String[] args) {WeiBo weibo = new WeiBo();weibo.initTable();weibo.testPublishContent(weibo);weibo.testAddAttend(weibo);weibo.testShowMessage(weibo);weibo.testRemoveAttend(weibo);weibo.testShowMessage(weibo); }總結
以上是生活随笔為你收集整理的【14笔记】HBase实战--微博案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学技能需要怎样配置的电脑?
- 下一篇: 杰理之WDT【篇】