美文网首页
redis系列篇(二):redis实例演练一

redis系列篇(二):redis实例演练一

作者: 面朝大海_1234 | 来源:发表于2017-12-25 21:23 被阅读0次

    需求如下:

    1、用户可以发布文章或者帖子,每个用户发布的信息,从发布日期开始算,只能在一周内被点赞,且不能被同一个用户重复点赞。

    2、文章或者帖子信息可以按照积分或者时间来进行排序,且能够分页显示。

    3、每个用户发布的文章应该归属到一个组里面,例如张三发布的属于科技篇和互联网篇,李四发布的属于互联网篇和人工智能篇,王五发布的属于互联网篇

    4、归组以后可以查询出任何组与组之间交集的文章或者帖子信息。

    需求分析:

    1、首先我们需要知道文章信息应该用redis哪种方式去存储,纵观其五种存储方式,选择了hash,为什么呢,因为hash方便扩展和维护,后期需要修改里面某个字段内容非常方便或者新增字段也非常方便。

    2、控制一周内部被重复点赞,则直接设置文章的点赞过期时间即可,每次点赞前先判断文章是否有效

    3、控制重复点赞用set方式存储,技能统计点赞用户集合,又能控制重复

    4、既然涉及到排序,那么毫无疑问用sortSet方式存储

    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;//每周多少秒  控制点赞过期时间

    private static final int VOTE_SCORE = 10;//点赞积分

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

    static Jedis jedis=null;

    static{

    jedis=new Jedis("127.0.0.1");

    }

    /**

    * 用户发布文章信息

    * @param wzzt   文章主题

    * @param wznr文章内容

    * @param wzzb   文章组别   多个用逗号","隔开

    * @param username  用户名

    * @return

    */

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

    try {

    /**

    * 用hash方式存放文章信息(hash方式方便扩展子弹和修改数据)

    */

    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()));//文章发布时间

    articleMap.put("votes", "1");//初始化文章的点赞信息

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

    /**

    * 控制文章点赞的过期时间为一周(set集合可以去重,设置过期时间)

    */

    jedis.sadd("voted:"+id, username);//默认存在自己点赞信息

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

    /**

    * 存放文章对应积分和时间 --初始化积分为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];//遍历出每个组别的名称

    jedis.sadd("article_group:"+str, "article:"+id);//此处只能用set集合存放组别,因为需要取交集

    }

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

    return "1";

    } catch (Exception e) {

    System.out.println("文章发布异常!");

    return "-1";

    }

    }

    /**

    * 点赞操作

    * @param wzid        文章ID

    * @param username    点赞用户

    * @return

    */

    public int votedArticle(String wzid,String username){

    try {

    //文章只有在一周内才可以被点赞,在发布文章的时候此处的key过期时间为1周

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

    //判断是否用户重复点赞

    long num=jedis.sadd("voted:"+wzid, username);//因为当用户点赞后,此处再次新增时结果为0

    if(num==1){

    System.out.println(username+"点赞成功");

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

    jedis.hincrBy("article:"+wzid, "votes", 1L);//修改hash里面的点赞数量

    return 1;

    }else{

    System.out.println(username+"不允许重复点赞");

    return -1;

    }

    }else{

    System.out.println("文章已超过点赞时间,不允许点赞");

    return -1;

    }

    } catch (Exception e) {

    System.out.println("文章点赞异常!");

    return -1;

    }

    }

    /**

    * 分页倒序查询文章信息

    * @param type   1-按照积分  2-按照时间

    * @param pageNum 当前页数

    * @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;

    }

    /**

    * 分组获取对应文章信息

    * 此处分组交集查询是不能按照规则去排序的,

    * 如果需要排序,可以在hash里面加时间和积分或者点赞数量字段后,直接将此处的List集合按照对应条件进行排序

    * @param groups   组别 按照逗号分隔 ","

    * @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();

    /**

    * 第一步:张三 、李四 、王五各发布一篇文章,

    *      其中张三发布文章为科技(technology)篇和互联网(internet)篇

    *      李四发布文章互联网(internet)篇和人工智能(artificial)篇

    *      王五发布的属于互联网(internet)篇

    //jedis.flushDB();

    test.postArticle("张三测试", "张三发布的问内容为科技篇和互联网篇", "technology,internet", "zhangsan");

    // test.postArticle("李四测试", "李四发布文章互联网和人工智能", "internet,artificial", "lisi");

    // test.postArticle("王五测试", "王五发布的为互联网篇", "internet", "wangwu");

    */

    /**

    * 第二步:

    * 李四和王五都点赞张三           张三的文章ID=20170725143410

    * 王五点赞李四李四的文章ID=20170725143502

    * 王五再次点赞张三王五的文章ID=20170725143532

    */

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

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

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

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

    /**

    * 第三步:此时查询出所有文章内容

    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("==========按照时间倒叙排序start==========");

    System.out.println(resultLists2);

    System.out.println("==========按照时间倒叙排序end==========");*/

    /**

    *第四步:

    *    查询和互联网相关的文章

    *    查询出互联网 、科技相关的文章

    */

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

    System.out.println("==========按照组别交集查询为互联网的文章start==========");

    System.out.println(resultLists3);

    System.out.println("==========按照组别交集查询为互联网的文章end==========");*/

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

    System.out.println("==========按照组别交集查询为互联网且为科技的文start==========");

    System.out.println(resultLists4);

    System.out.println("==========按照组别交集查询为互联网且为科技的文end==========");

    }

    }

    总结分析:实际上很多人会疑问,一篇文章或者帖子起始数据量很大,redis能否承受,当然,文章的整篇内容是不适合存放在redis中的,毕竟数据量比较大,所以这里适合去存放每篇文章或者帖子的简单主题介绍,这样无论是在PC端还是APP端都可以很快查询出对应的列表信息,当点击某一篇文章时,再去mysql或者oracle数据库查询整篇文章详情。

    相关文章

      网友评论

          本文标题:redis系列篇(二):redis实例演练一

          本文链接:https://www.haomeiwen.com/subject/akergxtx.html