• Redis实现文章投票功能


    Redis的具体操作这里就不说了,说一下需求和设计思路。

    需求:自己实现一个文章投票的功能
    1.能够按照时间分页倒叙查看文章信息
    2.能够给文章投票,一个用户给一篇文章只能投票一次
    3.需要记录分值。每次投票后就+10分

    思路:
    1.设计一个Hash,用于存储文章的基本信息(标题、内容、创建人)。键:article:1
    2.设计一个Set,用于记录一篇文章被哪些用户投过票。键:vole:1
    3.设计一个ZSet,用于记录每一篇文章的分值。键:score

    RedisUtil.java

    package cn.duanjt;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    /**
     * Redis公共操作类
     * @author 段江涛
     * @date 2018-12-29
     */
    public class RedisUtil {
        JedisPool pool = null;
    
        public RedisUtil(String host, int port) {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(20);
            config.setMaxIdle(5);
            config.setMaxWaitMillis(100);
            config.setTestOnBorrow(true);
    
            pool = new JedisPool(config, host, port);
        }
        
        public Jedis getJedis(){
            return pool.getResource();
        }
        
        public void dispose(Jedis jedis){
            pool.returnResourceObject(jedis);
        }
    }
    View Code

     AppTest.java (测试代码)

    package cn.duanjt;
    
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Set;
    
    import org.junit.Before;
    import org.junit.Test;
    
    import redis.clients.jedis.Jedis;
    
    public class AppTest {
        RedisUtil redis = null;
        int userId = 200;//用户编号,可修改后执行下面的相关方法
        int artId = 3;//文章编号,可修改后执行下面的相关方法
    
        /**
         * 初始化
         */
        @Before
        public void load() {
            String host = "172.23.88.107";
            int port = 6379;
            redis = new RedisUtil(host, port);
        }
    
        /**
         * 发表文章
         * 逻辑:
         * 1.文章编号采用incr方法自增长
         * 2.定义Redis的Hash类型存放文章信息,键采用 "article:"+文章编号的方式
         * 3.定义Set用于记录哪些用户给这篇文章投过票,键采用 "vole:"+文章编号的方式
         * 4.定义ZSet用于记录每篇文章的分值,方便排序,键使用"score"
         */
        @Test
        public void addArticle() {
            Jedis jedis = redis.getJedis();
            // 定义发布文章:编号、标题、内容、创建人 Hash
            HashMap<String, String> map = new HashMap<String, String>();
            long id = jedis.incr("article:");// 文章id,自增长
            map.put("title", "文章标题->" + id);
            map.put("content", "文章内容->" + id);
            map.put("user_id", String.valueOf(userId));
            map.put("create_time", getDate());
            jedis.hmset("article:" + id, map);
    
            // 自己给自己投上一票 Set
            jedis.sadd("vole:" + id, userId + "");
            // 给自己+10分 ZSet
            jedis.zadd("score", 10, id + "");
    
            printArticle(jedis, id);
    
            redis.dispose(jedis);
        }
    
        /**
         * 给文章投票
         * 逻辑:
         * 1.记录文章投票用户集合的Set新增一条数据sadd,如果返回1表示新增成功,返回0表示已存在
         * 2.记录分值的ZSet调用zincrby方法加10分
         */
        @Test
        public void voteArticle() {
            Jedis jedis = redis.getJedis();
            try {
                // 查找文章
                if (!jedis.exists("article:" + artId)) {
                    System.out.println("文章:" + artId + " 不存在.");
                    return;
                }
                // 用户投票
                if (jedis.sadd("vole:" + artId, userId + "") == 0) {
                    System.out.println("用户:" + userId + " 已对文章:" + artId + " 进行过投票,不可重复投票");
                    return;
                }
                // +10分
                jedis.zincrby("score", 10, artId + "");
                printArticle(jedis, artId);
            } finally {
                redis.dispose(jedis);
            }
        }
    
        /**
         * 查看文章信息
         * 逻辑:就是简单的Hash的数据获取hmget
         */
        @Test
        public void detailArticle() {
            Jedis jedis = redis.getJedis();
            try {
                printArticle(jedis, artId);
            } finally {
                redis.dispose(jedis);
            }
        }
    
        /**
         * 按分值从高到低排序
         * 1.调用ZSet的zrevrange方法根据分值倒序,获得一个集合
         * 2.循环集合去Hash中查询文章信息
         */
        @Test
        public void allArticle() {
            Jedis jedis = redis.getJedis();
            try {
                Set<String> set = jedis.zrevrange("score", 0, 1000);// 返回的是文章编号
                for (String aId : set) {
                    System.out.println("<<=================================================>>");
                    printArticle(jedis, Integer.parseInt(aId));
                }
    
            } finally {
                redis.dispose(jedis);
            }
        }
    
        /**
         * 打印文章信息,参数是文章的id
         * @param jedis
         * @param id
         */
        private void printArticle(Jedis jedis, long id) {
            /* 打印日志 */
            System.out.println("***********************");
            List<String> list = jedis.hmget("article:" + id, "title", "content", "user_id", "create_time");
            System.out.println("文章编号:" + id);
            System.out.println("文章标题:" + list.get(0));
            System.out.println("文章内容:" + list.get(1));
            System.out.println("发布用户:" + list.get(2));
            System.out.println("发布时间:" + list.get(3));
            System.out.println("***********************");
            double card = jedis.zscore("score", id + "");
            System.out.println("文章分值:" + card);
    
            Set<String> set = jedis.smembers("vole:" + id);
            System.out.println("给文章投票的用户有:" + String.join(",", set));
        }
    
        /**
         * 获取当前时间
         * @return
         */
        private String getDate() {
            java.text.DateFormat format1 = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String s = format1.format(new Date());
            return s;
        }
    
    }

    总结:

    1.使用Redis之前一定要先设计好,写代码才能保证思路清晰。

    2.设计和思路文档一定要保存好,不然其它同事接手会很懵逼。

    3.上面的两个类,拷过去就可以执行,看效果。

  • 相关阅读:
    聪明的质检员 (二分)
    分巧克力(二分)
    产生冠军 HDU
    Legal or Not HDU
    确定比赛名次 HDU
    最短路径问题 HDU
    dijkstra算法为什么不能有负边?
    最短路 HDU
    dijkstra算法 模板
    Floyd算法模板--详解
  • 原文地址:https://www.cnblogs.com/duanjt/p/10197102.html
Copyright © 2020-2023  润新知