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.上面的兩個類,拷過去就可以執行,看效果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM