redis系列篇(二):redis實(shí)例演練一

需求如下:

1蕊温、用戶可以發(fā)布文章或者帖子,每個(gè)用戶發(fā)布的信息遏乔,從發(fā)布日期開始算义矛,只能在一周內(nèi)被點(diǎn)贊,且不能被同一個(gè)用戶重復(fù)點(diǎn)贊盟萨。

2凉翻、文章或者帖子信息可以按照積分或者時(shí)間來進(jìn)行排序,且能夠分頁顯示捻激。

3制轰、每個(gè)用戶發(fā)布的文章應(yīng)該歸屬到一個(gè)組里面,例如張三發(fā)布的屬于科技篇和互聯(lián)網(wǎng)篇胞谭,李四發(fā)布的屬于互聯(lián)網(wǎng)篇和人工智能篇垃杖,王五發(fā)布的屬于互聯(lián)網(wǎng)篇

4、歸組以后可以查詢出任何組與組之間交集的文章或者帖子信息丈屹。

需求分析:

1缩滨、首先我們需要知道文章信息應(yīng)該用redis哪種方式去存儲(chǔ),縱觀其五種存儲(chǔ)方式泉瞻,選擇了hash脉漏,為什么呢,因?yàn)閔ash方便擴(kuò)展和維護(hù)袖牙,后期需要修改里面某個(gè)字段內(nèi)容非常方便或者新增字段也非常方便侧巨。

2、控制一周內(nèi)部被重復(fù)點(diǎn)贊鞭达,則直接設(shè)置文章的點(diǎn)贊過期時(shí)間即可司忱,每次點(diǎn)贊前先判斷文章是否有效

3皇忿、控制重復(fù)點(diǎn)贊用set方式存儲(chǔ),技能統(tǒng)計(jì)點(diǎn)贊用戶集合坦仍,又能控制重復(fù)

4鳍烁、既然涉及到排序,那么毫無疑問用sortSet方式存儲(chǔ)

5繁扎、這里注意到無論是交集幔荒、并集、差集都只能用set集合去存梳玫。

代碼如下:

package redis.clients.test;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Set;

import org.junit.Test;

import redis.clients.jedis.Jedis;

import redis.clients.util.DateTimeUtil;

public class D01_Test {

private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;//每周多少秒 ?控制點(diǎn)贊過期時(shí)間

private static final int VOTE_SCORE = 10;//點(diǎn)贊積分

private static final int ARTICLES_PER_PAGE = 25;//每頁多少篇文章

static Jedis jedis=null;

static{

jedis=new Jedis("127.0.0.1");

}

/**

* 用戶發(fā)布文章信息

* @param wzzt ? 文章主題

* @param wznr文章內(nèi)容

* @param wzzb ? 文章組別 ? 多個(gè)用逗號(hào)","隔開

* @param username ?用戶名

* @return

*/

public String postArticle(String wzzt,String wznr,String wzzb,String username){

try {

/**

* 用hash方式存放文章信息(hash方式方便擴(kuò)展子彈和修改數(shù)據(jù))

*/

String id=DateTimeUtil.getDateSecondFormatNoSplit(new Date());

Map articleMap=new HashMap();

articleMap.put("wzzt", wzzt);

articleMap.put("wzid", id);

articleMap.put("wznr", wznr);

articleMap.put("username", username);

articleMap.put("fbsj", DateTimeUtil.getDateSecondFormat(new Date()));//文章發(fā)布時(shí)間

articleMap.put("votes", "1");//初始化文章的點(diǎn)贊信息

jedis.hmset("article:"+id, articleMap);

/**

* 控制文章點(diǎn)贊的過期時(shí)間為一周(set集合可以去重爹梁,設(shè)置過期時(shí)間)

*/

jedis.sadd("voted:"+id, username);//默認(rèn)存在自己點(diǎn)贊信息

jedis.expire("voted:"+id, ONE_WEEK_IN_SECONDS);

/**

* 存放文章對(duì)應(yīng)積分和時(shí)間 --初始化積分為100 ?(排序必須用sortSet集合方式)

*/

jedis.zadd("article_score:", 100, "article:"+id);

jedis.zadd("article_time:", System.currentTimeMillis() / 1000, "article:"+id);

/**

* 分組存放文章信息 (只有set集合才可以去交集、并集提澎、差集)

*/

String[] wzzbs=wzzb.split(",");

for (int i = 0; i < wzzbs.length; i++) {

String str=wzzbs[i];//遍歷出每個(gè)組別的名稱

jedis.sadd("article_group:"+str, "article:"+id);//此處只能用set集合存放組別姚垃,因?yàn)樾枰〗患?/p>

}

System.out.println(username+"============文章發(fā)布成功===========");

return "1";

} catch (Exception e) {

System.out.println("文章發(fā)布異常!");

return "-1";

}

}

/**

* 點(diǎn)贊操作

* @param wzid ? ? ? ?文章ID

* @param username ? ?點(diǎn)贊用戶

* @return

*/

public int votedArticle(String wzid,String username){

try {

//文章只有在一周內(nèi)才可以被點(diǎn)贊盼忌,在發(fā)布文章的時(shí)候此處的key過期時(shí)間為1周

if(jedis.exists("voted:"+wzid)){

//判斷是否用戶重復(fù)點(diǎn)贊

long num=jedis.sadd("voted:"+wzid, username);//因?yàn)楫?dāng)用戶點(diǎn)贊后积糯,此處再次新增時(shí)結(jié)果為0

if(num==1){

System.out.println(username+"點(diǎn)贊成功");

jedis.zincrby("article_score:", VOTE_SCORE, "article:"+wzid);//加積分

jedis.hincrBy("article:"+wzid, "votes", 1L);//修改hash里面的點(diǎn)贊數(shù)量

return 1;

}else{

System.out.println(username+"不允許重復(fù)點(diǎn)贊");

return -1;

}

}else{

System.out.println("文章已超過點(diǎn)贊時(shí)間,不允許點(diǎn)贊");

return -1;

}

} catch (Exception e) {

System.out.println("文章點(diǎn)贊異常谦纱!");

return -1;

}

}

/**

* 分頁倒序查詢文章信息

* @param type ? 1-按照積分 ?2-按照時(shí)間

* @param pageNum 當(dāng)前頁數(shù)

* @return

*/

public List> getArticles(String type,int pageNum){

List> lists=new ArrayList>();

try {

int start = (pageNum - 1) * ARTICLES_PER_PAGE;//0

int end = start + ARTICLES_PER_PAGE - 1;//24

if("1".equals(type)){

Set sets= jedis.zrevrange("article_score:", start, end);

for (String id : sets) {

Map data=jedis.hgetAll(id);

lists.add(data);

}

}else{

Set sets= jedis.zrevrange("article_time:", start, end);

for (String id : sets) {

Map data=jedis.hgetAll(id);

lists.add(data);

}

}

} catch (Exception e) {

System.out.println("查詢文章信息失敗");

}

return lists;

}

/**

* 分組獲取對(duì)應(yīng)文章信息

* 此處分組交集查詢是不能按照規(guī)則去排序的絮宁,

* 如果需要排序,可以在hash里面加時(shí)間和積分或者點(diǎn)贊數(shù)量字段后服协,直接將此處的List集合按照對(duì)應(yīng)條件進(jìn)行排序

* @param groups ? 組別 按照逗號(hào)分隔 ","

* @return

*/

public List> getArticlesByGroup(String groups){

List> lists=new ArrayList>();

try {

String[] strs=groups.split(",");

Set sets= jedis.sinter(strs);

for (String id : sets) {

Map data=jedis.hgetAll(id);

lists.add(data);

}

} catch (Exception e) {

System.out.println("分組查詢文章信息失敗");

}

return lists;

}

@Test

public void testD01_Test(){

D01_Test test=new D01_Test();

/**

* 第一步:張三 绍昂、李四 、王五各發(fā)布一篇文章偿荷,

* ? ? ?其中張三發(fā)布文章為科技(technology)篇和互聯(lián)網(wǎng)(internet)篇

* ? ? ?李四發(fā)布文章互聯(lián)網(wǎng)(internet)篇和人工智能(artificial)篇

* ? ? ?王五發(fā)布的屬于互聯(lián)網(wǎng)(internet)篇

//jedis.flushDB();

test.postArticle("張三測(cè)試", "張三發(fā)布的問內(nèi)容為科技篇和互聯(lián)網(wǎng)篇", "technology,internet", "zhangsan");

// test.postArticle("李四測(cè)試", "李四發(fā)布文章互聯(lián)網(wǎng)和人工智能", "internet,artificial", "lisi");

// test.postArticle("王五測(cè)試", "王五發(fā)布的為互聯(lián)網(wǎng)篇", "internet", "wangwu");

*/

/**

* 第二步:

* 李四和王五都點(diǎn)贊張三 ? ? ? ? ? 張三的文章ID=20170725143410

* 王五點(diǎn)贊李四李四的文章ID=20170725143502

* 王五再次點(diǎn)贊張三王五的文章ID=20170725143532

*/

// test.votedArticle("20170725143410","lisi");

//test.votedArticle("20170725143410","wangwu");

// test.votedArticle("20170725143502","wangwu");

// test.votedArticle("20170725143410","wangwu");

/**

* 第三步:此時(shí)查詢出所有文章內(nèi)容

List> resultLists=test.getArticles("1", 1);

System.out.println("==========按照積分倒敘排序start==========");

System.out.println(resultLists);

System.out.println("==========按照積分倒敘排序end==========");

List> resultLists2=test.getArticles("2", 1);

System.out.println("==========按照時(shí)間倒敘排序start==========");

System.out.println(resultLists2);

System.out.println("==========按照時(shí)間倒敘排序end==========");*/

/**

*第四步:

* ? ?查詢和互聯(lián)網(wǎng)相關(guān)的文章

* ? ?查詢出互聯(lián)網(wǎng) 窘游、科技相關(guān)的文章

*/

/* List> resultLists3=test.getArticlesByGroup("article_group:internet");

System.out.println("==========按照組別交集查詢?yōu)榛ヂ?lián)網(wǎng)的文章start==========");

System.out.println(resultLists3);

System.out.println("==========按照組別交集查詢?yōu)榛ヂ?lián)網(wǎng)的文章end==========");*/

List> resultLists4=test.getArticlesByGroup("article_group:internet,article_group:technology");

System.out.println("==========按照組別交集查詢?yōu)榛ヂ?lián)網(wǎng)且為科技的文start==========");

System.out.println(resultLists4);

System.out.println("==========按照組別交集查詢?yōu)榛ヂ?lián)網(wǎng)且為科技的文end==========");

}

}

總結(jié)分析:實(shí)際上很多人會(huì)疑問,一篇文章或者帖子起始數(shù)據(jù)量很大跳纳,redis能否承受忍饰,當(dāng)然,文章的整篇內(nèi)容是不適合存放在redis中的寺庄,畢竟數(shù)據(jù)量比較大艾蓝,所以這里適合去存放每篇文章或者帖子的簡單主題介紹,這樣無論是在PC端還是APP端都可以很快查詢出對(duì)應(yīng)的列表信息斗塘,當(dāng)點(diǎn)擊某一篇文章時(shí)赢织,再去mysql或者oracle數(shù)據(jù)庫查詢整篇文章詳情。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末馍盟,一起剝皮案震驚了整個(gè)濱河市于置,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贞岭,老刑警劉巖八毯,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搓侄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡话速,警方通過查閱死者的電腦和手機(jī)讶踪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泊交,“玉大人乳讥,你說我怎么就攤上這事』詈希” “怎么了雏婶?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵物赶,是天一觀的道長白指。 經(jīng)常有香客問我,道長酵紫,這世上最難降的妖魔是什么告嘲? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮奖地,結(jié)果婚禮上橄唬,老公的妹妹穿的比我還像新娘。我一直安慰自己参歹,他們只是感情好仰楚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著犬庇,像睡著了一般僧界。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上臭挽,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天捂襟,我揣著相機(jī)與錄音,去河邊找鬼欢峰。 笑死葬荷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纽帖。 我是一名探鬼主播宠漩,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼懊直!你這毒婦竟也來了哄孤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤吹截,失蹤者是張志新(化名)和其女友劉穎瘦陈,沒想到半個(gè)月后凝危,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晨逝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年蛾默,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捉貌。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡支鸡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出趁窃,到底是詐尸還是另有隱情牧挣,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布醒陆,位于F島的核電站瀑构,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏刨摩。R本人自食惡果不足惜寺晌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望澡刹。 院中可真熱鬧呻征,春花似錦、人聲如沸罢浇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嚷闭。三九已至攒岛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凌受,已是汗流浹背阵子。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胜蛉,地道東北人挠进。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像誊册,于是被迫代替她去往敵國和親领突。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 大概在好幾年前就已經(jīng)聽過很多公司都在使用nosql數(shù)據(jù)庫案怯,只是在最近一兩年才在自己的項(xiàng)目當(dāng)中具體使用到君旦,實(shí)際上每種...
    面朝大海_1234閱讀 747評(píng)論 0 1
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法金砍,繼承相關(guān)的語法局蚀,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器痘系,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • NOSQL類型簡介鍵值對(duì):會(huì)使用到一個(gè)哈希表,表中有一個(gè)特定的鍵和一個(gè)指針指向特定的數(shù)據(jù)稽屏,如redis,volde...
    MicoCube閱讀 3,981評(píng)論 2 27
  • 隨著鬧鐘的想起澎羞,我極不情愿的爬起來。睡夢(mèng)中我夢(mèng)見自己終于成就了自己的夢(mèng)想……開豪車敛苇、美女坐懷妆绞、終于走上人生巔峰,但...
    珍惜最后閱讀 358評(píng)論 0 0