Redis 的zset使用

package com.moon.home.controller;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * redis的zset使用
 */
@Controller
@RequestMapping(value = "/redis/zset")
public class ZsetController extends BaseController {
	private static final Logger LOGGER = LoggerFactory.getLogger(ZsetController.class);

	private static final String ZSET_KEY = "zset_test_key";

	@Autowired
	private RedisTemplate redisTemplate;

    /**
     * 0、向zset中初始化10個元素
     * @return
     */
    @RequestMapping(value = "/init")
    @ResponseBody
    public String init() {
        for (int i = 0; i < 12; i++) {
            String userIdStr = "" + (i + 1);
            double scoreDou = (i + 1) * 100;
            redisTemplate.opsForZSet().add(ZSET_KEY, userIdStr, scoreDou);
        }
        // 獲取全部元素
        Set<ZSetOperations.TypedTuple<Object>> listSet = redisTemplate.opsForZSet().reverseRangeWithScores(ZSET_KEY, 0, -1);
        return JSON.toJSONString(listSet);
    }

    /**
     * 一、向zset中添加一個元素
     * @param userId
     * @param score
     * @return
     */
	@RequestMapping(value = "/add")
	@ResponseBody
	public String zset(Long userId, Double score) {
	    // 必須將Long 轉爲 String , 不然包類型轉換錯誤
        boolean isOk = redisTemplate.opsForZSet().add(ZSET_KEY, userId.toString(), score);

        return JSON.toJSONString(isOk);
	}

    /**
     * 二、根據userId獲取對應的分數
     * @return
     */
    @RequestMapping(value = "/getScoreByUserId")
    @ResponseBody
    public String getScoreByUserId(Long userId) {
        Double score = redisTemplate.opsForZSet().score(ZSET_KEY, userId.toString());
        if (score == null) {
            score = 0d;
        }
        return score.toString();
    }

    /**
     * 三、根據分數倒序排(分數高--到--分數低),取5條數據的userId
     *
     * @return
     */
    @RequestMapping(value = "/getTop5UserId")
    @ResponseBody
    public String getTop5UserId() {
        // 倒序取5條數據
        int topNum = 5;
        Set<Object> userIdSet = redisTemplate.opsForZSet().reverseRange(ZSET_KEY, 0, topNum - 1);
        return JSON.toJSONString(userIdSet);
    }

    /**
     * 四、根據分數倒序排(分數高--到--分數低),取5條數據的userId、score
     * @return
     */
    @RequestMapping(value = "/getTop5UserIdAndScore")
    @ResponseBody
    public String getTop5UserIdAndScore() {
        List<Map<String, Object>> list = new ArrayList<>();
        // 倒序取5條數據
        int topNum = 5;
        // 倒序排序獲取value和分數
        Set<ZSetOperations.TypedTuple<Object>> listSet = redisTemplate.opsForZSet().reverseRangeWithScores(ZSET_KEY, 0, topNum - 1);
        Iterator<ZSetOperations.TypedTuple<Object>> iterator = listSet.iterator();
        while (iterator.hasNext()) {
            ZSetOperations.TypedTuple<Object> typedTuple = iterator.next();
            Object value = typedTuple.getValue();
            double score = typedTuple.getScore();

            Map<String, Object> map = new HashMap<>();
            map.put("userId", Long.parseLong(value.toString()));
            map.put("score", score);
            list.add(map);
        }
        return JSON.toJSONString(list);
    }

    /**
     * 五、設置key的有效期
     * @return
     */
    @RequestMapping(value = "/expireAt")
    @ResponseBody
    public String expireAt() {
        // 當前時間加100秒過時
        Date expireDate = org.joda.time.DateTime.now().plusSeconds(100).toDate();

        redisTemplate.expireAt(ZSET_KEY, expireDate);

        Long expireTime = redisTemplate.getExpire(ZSET_KEY);

        return expireTime.toString();
    }

    /**
     * 六、刪除超過最大數量的元素
     * @return
     */
    @RequestMapping(value = "/removeOverNum")
    @ResponseBody
    public String removeOverNum() {
        int maxNum = 9;
        long redisNum = redisTemplate.opsForZSet().size(ZSET_KEY);
        // key存在且超出limit
        if (redisNum > maxNum) {
            // 從頭刪除redisNum - maxNum個元素(升序)
            redisTemplate.opsForZSet().removeRange(ZSET_KEY, 0, redisNum - maxNum - 1);
        }

        Set<ZSetOperations.TypedTuple<Object>> listSet = redisTemplate.opsForZSet().reverseRangeWithScores(ZSET_KEY, 0, -1);
        return JSON.toJSONString(listSet);
    }

    /**
     * 七、key是否存在
     * @return
     */
    @RequestMapping(value = "/hasKey")
    @ResponseBody
    public Boolean hasKey() {
        return redisTemplate.hasKey(ZSET_KEY);
    }


}
相關文章
相關標籤/搜索