Redis实战之年会抽奖

Redis实战之年会抽奖_第1张图片

前言

上一篇:Redis实战之微博点赞

本篇涉及相关命令:Sadd、Spop

示例基于SpringBoot 2.7.14

Sadd

Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合。

返回值:被添加到集合中的新元素的数量,不包括被忽略的元素。

Spop

Spop 命令用于移除并返回集合中的一个随机元素。

示例

年会抽奖就是分1、2、3等奖,再来一些安慰奖。比如说一等奖抽1个人,那从公司员工号中随机抽取一个,再将该号码剔除,也就是每个人最多一次中奖。

controller

/**
 * @author lonewalker
 */
@RequestMapping("/redis")
@RestController
public class RedisController {
     /**
     * 初始化数据
     * @return 提示信息
     */
    @GetMapping("/init")
    public String init(){
        return redisSetService.init();
    }

    /**
     * 抽奖
     * @return 用户id
     */
    @GetMapping("/prizeDraw")
    public Integer prizeDraw(){
        return redisSetService.prizeDraw();
    }
}   

Service

/**
 * @author lonewalker
 */
@Slf4j
@Service
public class RedisSetService {

   /**
     *提前先把数据刷新到redis缓存中。
     */
    public String init(){
        log.info("启动初始化..........");
        Boolean checkResult=RedisUtil.checkKey(RedisKey.PRIZE_KEY);
        if(!checkResult){
            //模拟加入工号  从DB查询
            Integer[] employees = new Integer[10];
            for (int i = 0; i < 10; i++) {
                employees[i] = i+1;
            }
            RedisUtil.setAdd(RedisKey.PRIZE_KEY,employees);
        }
        return "初始化数据完成";
    }

    public Integer prizeDraw(){
        String key = RedisKey.PRIZE_KEY;
        Object userId = RedisUtil.setPop(key);
        if (ObjectUtil.isNotNull(userId)){
            return (Integer) userId;
        }
        return 0;

}

RedisUtil

/**
 * @author lonewalker
 */
@Slf4j
@Component
public class RedisUtil {
    private static RedisTemplate redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisUtil.redisTemplate = redisTemplate;
    }

        /**
     * 检查是否已存在key
     * @param key 键
     * @return true代表已存在
     */
    public static Boolean checkKey(String key){
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

        /**
     * 将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。
     * @param key     键
     * @param values  值
     * @return 被添加到集合中的新元素的数量,不包括被忽略的元素。
     */
    public static Long setAdd(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

        /**
     * 用于移除并返回集合中的一个随机元素。
     * @param key 键
     * @return 被移除的随机元素。 当集合不存在或是空集时,返回 nil 。
     */
    public static Object setPop(String key){
        try {
            return redisTemplate.opsForSet().pop(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

常量

public class RedisKey {

    /**
     * 抽奖
     */
    public static final String PRIZE_KEY = "prize";
    
}

测试

抽到4号

Redis实战之年会抽奖_第2张图片

就把4号剔除了

Redis实战之年会抽奖_第3张图片

扩展

Srandmember 命令用于返回集合中的一个随机元素。Srandmember 命令接受可选的 count 参数:

  • 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
  • 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。

该操作和 Spop 相似,但 Spop 将随机元素从集合中移除并返回,而 Srandmember 则仅仅返回随机元素,而不对集合进行任何改动。

你可能感兴趣的:(redis)