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); } }