《Redis实战》学习实践

序:

最近急需学习Redis相关内容,因此阅读了一本相当不错的书籍:《Redis实战》,在这里记录学习的过程以及遇到的问题。

一、第一章  根据文章点赞及发布日期list文章

业务:

全部代码示例:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ZParams;

import java.util.*;

public class Chapter01 {
    private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;
    private static final int VOTE_SCORE = 432;
    private static final int ARTICLES_PER_PAGE = 25;

    public static final void main(String[] args) {
        new Chapter01().run();
    }

    public void run() {
        Jedis conn = new Jedis("localhost");
        conn.select(15);

        String articleId = postArticle(
            conn, "username", "A title", "http://www.google.com");
        System.out.println("We posted a new article with id: " + articleId);
        System.out.println("Its HASH looks like:");
        Map<String,String> articleData = conn.hgetAll("article:" + articleId);
        for (Map.Entry<String,String> entry : articleData.entrySet()){
            System.out.println("  " + entry.getKey() + ": " + entry.getValue());
        }

        System.out.println();

        articleVote(conn, "other_user", "article:" + articleId);
        String votes = conn.hget("article:" + articleId, "votes");
        System.out.println("We voted for the article, it now has votes: " + votes);
        assert Integer.parseInt(votes) > 1;

        System.out.println("The currently highest-scoring articles are:");
        List<Map<String,String>> articles = getArticles(conn, 1);
        printArticles(articles);
        assert articles.size() >= 1;

        addGroups(conn, articleId, new String[]{"new-group"});
        System.out.println("We added the article to a new group, other articles include:");
        articles = getGroupArticles(conn, "new-group", 1);
        printArticles(articles);
        assert articles.size() >= 1;
    }

    public String postArticle(Jedis conn, String user, String title, String link) {
        String articleId = String.valueOf(conn.incr("article:"));

        String voted = "voted:" + articleId;
        conn.sadd(voted, user);
        conn.expire(voted, ONE_WEEK_IN_SECONDS);

        long now = System.currentTimeMillis() / 1000;
        String article = "article:" + articleId;
        HashMap<String,String> articleData = new HashMap<String,String>();
        articleData.put("title", title);
        articleData.put("link", link);
        articleData.put("user", user);
        articleData.put("now", String.valueOf(now));
        articleData.put("votes", "1");
        conn.hmset(article, articleData);
        conn.zadd("score:", now + VOTE_SCORE, article);
        conn.zadd("time:", now, article);

        return articleId;
    }

    public void articleVote(Jedis conn, String user, String article) {
        long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
        if (conn.zscore("time:", article) < cutoff){
            return;
        }

        String articleId = article.substring(article.indexOf(':') + 1);
        if (conn.sadd("voted:" + articleId, user) == 1) {
            conn.zincrby("score:", VOTE_SCORE, article);
            conn.hincrBy(article, "votes", 1);
        }
    }


    public List<Map<String,String>> getArticles(Jedis conn, int page) {
        return getArticles(conn, page, "score:");
    }

    public List<Map<String,String>> getArticles(Jedis conn, int page, String order) {
        int start = (page - 1) * ARTICLES_PER_PAGE;
        int end = start + ARTICLES_PER_PAGE - 1;

        Set<String> ids = conn.zrevrange(order, start, end);
        List<Map<String,String>> articles = new ArrayList<Map<String,String>>();
        for (String id : ids){
            Map<String,String> articleData = conn.hgetAll(id);
            articleData.put("id", id);
            articles.add(articleData);
        }

        return articles;
    }

    public void addGroups(Jedis conn, String articleId, String[] toAdd) {
        String article = "article:" + articleId;
        for (String group : toAdd) {
            conn.sadd("group:" + group, article);
        }
    }

    public List<Map<String,String>> getGroupArticles(Jedis conn, String group, int page) {
        return getGroupArticles(conn, group, page, "score:");
    }

    public List<Map<String,String>> getGroupArticles(Jedis conn, String group, int page, String order) {
        String key = order + group;
        if (!conn.exists(key)) {
            ZParams params = new ZParams().aggregate(ZParams.Aggregate.MAX);
            conn.zinterstore(key, params, "group:" + group, order);
            conn.expire(key, 60);
        }
        return getArticles(conn, page, key);
    }

    private void printArticles(List<Map<String,String>> articles){
        for (Map<String,String> article : articles){
            System.out.println("  id: " + article.get("id"));
            for (Map.Entry<String,String> entry : article.entrySet()){
                if (entry.getKey().equals("id")){
                    continue;
                }
                System.out.println("    " + entry.getKey() + ": " + entry.getValue());
            }
        }
    }
}

对文章进行分组:

群组功能由两个部分组成,一个部分负责记录文章属于哪个群组,另一个部分负责取出群组里的文章。为了记录群组里都保存了哪些文章,网站需要为每个群组创建一个集合,并将所有同属于一个群组的文章ID都记录到那个集合里。

package com.ual;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ZParams;

import java.util.*;

public class ArticleService {
    //设置过期时间
    private static final int One_Week_In_Seconds=7*86400;
    //设置评分常量:一天的秒数除以200(默认热门文章点赞数)
    private static final int Vote_Score=432;
    //设置分页展示文章数量
    private static final int Article_Pre_Page=25;
        /*发布并获取文章*/
    public String postArticle(Jedis conn,String user,String title,String link){
        //设置文章id,
        String articleId=String.valueOf(conn.incr("article:"));
        //创建指定文章点赞用户(用于防止重复点赞)
        String voted="voted:"+articleId;
        conn.sadd(voted,user);
        //设置点赞用户表的过期时间
        conn.expire(voted,One_Week_In_Seconds);

        long now=System.currentTimeMillis()/1000;
        String article="article:"+articleId;
        //文章数据存储在hash表中
        HashMap<String ,String> articleData=new HashMap<>();
        articleData.put("id",articleId);
        articleData.put("title",title);
        articleData.put("link",link);
        articleData.put("user",user);
        articleData.put("time",String.valueOf(now));
        articleData.put("votes","0");
        conn.hmset(article,articleData);
        conn.zadd("score:",now+Vote_Score,article);
        conn.zadd("time:",now,article);
        return articleId;
    }
    public void articleVote(Jedis conn,String user,String article){
        //设置过期时间
        long cutoff=(System.currentTimeMillis()/1000)-One_Week_In_Seconds;
        //如果文章已经发表七天了,点赞无效
        if(conn.zscore("time:",article)<cutoff){
            return;
        }
        String articleId=article.substring(article.indexOf(":")+1);
        if(conn.sadd("voted:"+articleId,user)==1){
            //score表中article分值加432
            conn.zincrby("score:",Vote_Score,article);
            //article表中votes字段加1
            conn.hincrBy(article,"votes",1);
        }
    }

    public List<Map<String,String>> getArticle(Jedis conn,int page,String order){
        //定义分页开始结束序号
        int start=(page-1)*Article_Pre_Page;
        int end=start+Article_Pre_Page-1;
        //从order(time:或score:)中取出全部文章id
        Set<String> ids=conn.zrevrange(order,start,end);
        //定义一个链表,存储要取出的全部文章
        List<Map<String,String>> articles=new ArrayList<>();
        for(String id:ids){
            //从对应文章表中取出文章数据(hgetAll为取出全部字段)
            Map<String,String> articleData=conn.hgetAll(id);
            articles.add(articleData);
        }
        return articles;
    }
    //添加分组分组 一篇文章可以属于多个群组
    public void addGroups(Jedis conn,String articleId,String[] toadd){
        String article="article:"+articleId;
        for (String group:toadd){
            conn.sadd("group"+group,article);
        }
    }
    public List<Map<String,String>> getGroupArticles(Jedis conn,String group,int page,String order){
        //为每个群组的每种排列顺序都创建一个键
        String key=order+group;
        if(!conn.exists(key)){
            ZParams params=new ZParams().aggregate(ZParams.Aggregate.MAX);
            //获取分组文章与排序文章id的交集存入key中,key中的排序方式依据排序文章的方式进行排序
            conn.zinterstore(key,params,"group:"+group,order);
            //设置过期时间为60s
            conn.expire(key,60);
        }
        return getArticle(conn,page,key);
    }
    public void  printArticles(List<Map<String,String>> articles){
        for(Map<String,String> article:articles){
            System.out.println("id:"+article.get("id"));
            for(Map.Entry<String,String> entry:article.entrySet()){
                if(entry.getKey().equals("id")){
                    continue;
                }
                System.out.println(" "+entry.getKey()+" : "+entry.getValue());
            }

        }
    }



}

猜你喜欢

转载自www.cnblogs.com/UalBlog/p/10913783.html
今日推荐