当前位置: 首页 > article >正文

java 抽奖程序结合数据库,redis实现

数据库脚本:

/**
 * SET NAMES utf8mb4;
 * SET FOREIGN_KEY_CHECKS = 0;
 *
 * -- ----------------------------
 * -- Table structure for prizes
 * -- ----------------------------
 * DROP TABLE IF EXISTS `prizes`;
 * CREATE TABLE `prizes` (
 *   `id` int NOT NULL AUTO_INCREMENT,
 *   `name` varchar(255) NOT NULL,
 *   `quantity` int NOT NULL,
 *   `weight` int NOT NULL DEFAULT '1',
 *   PRIMARY KEY (`id`)
 * ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
 *
 * -- ----------------------------
 * -- Records of prizes
 * -- ----------------------------
 BEGIN;
 INSERT INTO `prizes` (`id`, `name`, `quantity`, `weight`) VALUES (1, 'huawei mate60pro', 10, 5);
 INSERT INTO `prizes` (`id`, `name`, `quantity`, `weight`) VALUES (2, 'vivo pro13', 15, 15);
 INSERT INTO `prizes` (`id`, `name`, `quantity`, `weight`) VALUES (3, ' redmi 12', 69, 10);
 INSERT INTO `prizes` (`id`, `name`, `quantity`, `weight`) VALUES (4, '苹果16', 5, 5);
 INSERT INTO `prizes` (`id`, `name`, `quantity`, `weight`) VALUES (5, '谢谢惠顾!', 60, 65);
 COMMIT;
 *
 * SET FOREIGN_KEY_CHECKS = 1;
 */
@Component
public class Lottery {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String DB_URL = "jdbc:mysql://localhost:3306/splm?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "***";

    public String runLottery() {
        String result = "";
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            // 初始化奖品
            initializePrizes(conn);
            // 抽奖
            String prizeId = drawPrize();
            if (prizeId != null) {
                System.out.println(String.format("恭喜你,中奖奖品ID:%s,名称-%s", prizeId,redisTemplate.opsForValue().get("prize:"+prizeId+":name")));
                updateDatabase(conn, prizeId);
                result= String.format("恭喜你,中奖奖品ID:%s,名称-%s", prizeId,redisTemplate.opsForValue().get("prize:"+prizeId+":name"));
            } else {
                System.out.println("很遗憾,没有中奖。");
                result= "很遗憾,没有中奖。";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private void initializePrizes(Connection conn) throws Exception {
        String sql = "SELECT id,name, quantity, weight FROM prizes";
        try (PreparedStatement stmt = conn.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            while (rs.next()) {
                String prizeId = rs.getString("id");
                int quantity = rs.getInt("quantity");
                int weight = rs.getInt("weight");

                redisTemplate.opsForSet().add("prizes_set", prizeId);
                redisTemplate.opsForValue().set("prize:" + prizeId + ":quantity", String.valueOf(quantity));
                redisTemplate.opsForValue().set("prize:" + prizeId + ":name", rs.getString("name"));
                redisTemplate.opsForValue().set("prize:" + prizeId + ":weight", String.valueOf(weight));
            }
        }
    }

    private String drawPrize() {
        Random random = new Random();
        Set<String> prizeSet = redisTemplate.opsForSet().members("prizes_set");
        int totalWeight = 0;
        for (String prizeId : prizeSet) {
            totalWeight += Integer.parseInt(redisTemplate.opsForValue().get("prize:" + prizeId + ":weight"));
        }

        int randomWeight = random.nextInt(totalWeight);
        int currentWeight = 0;
        for (String prizeId : prizeSet) {
            currentWeight += Integer.parseInt(redisTemplate.opsForValue().get("prize:" + prizeId + ":weight"));
            if (randomWeight < currentWeight) {
                int quantity = Integer.parseInt(redisTemplate.opsForValue().get("prize:" + prizeId + ":quantity"));
                if (quantity > 0) {
                    redisTemplate.opsForValue().decrement("prize:" + prizeId + ":quantity");
                    return prizeId;
                }
            }
        }
        return null;
    }

    private void updateDatabase(Connection conn, String prizeId) throws Exception {
        String sql = "UPDATE prizes SET quantity = quantity - 1 WHERE id = ? and quantity>0";
        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, prizeId);
            stmt.executeUpdate();
        }
    }

}

调用:

@ApiOperation("模拟抽奖")
@PostMapping(value = "/getLottery")
public ResultVo getLottery() {
    String result = lottery.runLottery();
    return ResultVo.ok(result);
}

http://www.kler.cn/a/320952.html

相关文章:

  • 分布式微服务项目,同一个controller不同方法间的转发导致cookie丢失,报错null pointer异常
  • 《Java核心技术 卷I》用户界面AWT事件继承层次
  • Java爬虫(HttpURLConnection)详解
  • 思源笔记 Creating group siyuan (1000) permission denied (are you root?)
  • 自由学习记录(22)
  • 生成式GPT商品推荐:精准满足用户需求
  • golang操作mysql利器-gorm
  • Qt 每日面试题 -4
  • Linux 冯诺依曼体系结构与操作系统概念
  • 『功能项目』按钮的打开关闭功能【73】
  • 【 观测技术红外相机技术】
  • 算法_BFS解决多源最短路问题---持续更新
  • 恶意Bot流量识别分析实践
  • 设计模式实战——开发中常用到的单例模式
  • 预付费计量系统的实例
  • Ubuntu搭建java开发环境
  • element ui实现全局el-dialog可拖拽
  • unxiODBC编程(五)错误处理
  • 服务器为什么会受到网络攻击?
  • Ubuntu下简易安装openjdk8的命令行
  • 如何将MySQL卸载干净(win11)
  • table表格,让thead固定,tbody内容滚动,关键是都对齐的纯css写法
  • 前端问答:如何用 JavaScript 让 HTML Canvas全屏显示
  • Python--操作列表
  • uniapp EChars图表
  • 【Python报错已解决】TypeError: can only concatenate str (not “int“) to str