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

ops/2024/10/20 13:45:02/

数据库脚本:

/*** 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 {@Autowiredprivate 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.ppmy.cn/ops/119789.html

相关文章

RLHF 的启示:微调 LSTM 能更好预测股票?

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话: 在财务预测领域,准确预测股票价格是一项具有挑战性但至关重要的任务。传统方法通常难以应对股票市场固有的波动性和复杂性。这篇文章介绍了一种创新方法,该方法将长短期记忆 (LSTM) 网络与基于评…

DRF实操学习——文章和评论的设计

DRF实操学习——文章和评论的设计 1.文章表的设计2.文章表接口演示基础权限创建文章修改文章删除文章浏览所有文章 3.评论表的设计4.评论表接口演示1. 查询指定文章下的所有评论 1.文章表的设计 创建一个community的app 在settings中 完成注册 定义模型 创建文章表 from djan…

【Unity服务】如何使用Unity Version Control

Unity上的线上服务有很多&#xff0c;我们接触到的第一个一般就是Version Control&#xff0c;用于对项目资源的版本管理。 本文介绍如何为项目添加Version Control&#xff0c;并如何使用&#xff0c;以及如何将项目与Version Control断开链接。 其实如果仅仅是对项目资源进…

Clickhouse分布式表初体验

ClickHouse的分布式表是一种特殊类型的表&#xff0c;它允许你跨多个节点进行数据的查询和写入操作。以下是创建分布式表的步骤和案例&#xff1a; 1. 创建本地表&#xff1a; 在集群的每个节点上创建一个本地表&#xff0c;可以使用ReplicatedMergeTree系列引擎来实现数据…

电脑录屏怎么录视频和声音?苹果macOS、windows10都可以用的原神录屏工具来啦

在当今数字化时代&#xff0c;电脑录屏已经成为一项非常实用的技能&#xff0c;无论是制作教学视频、记录游戏精彩瞬间&#xff0c;还是进行线上会议演示&#xff0c;都离不开高质量的录屏。那么&#xff0c;电脑录屏怎么录视频和声音呢&#xff1f;今天就为大家详细介绍一下&a…

【数据库】 MongoDB 查看当前用户的角色和权限

在 MongoDB 中&#xff0c;可以通过一些简单的命令查看当前用户的角色和权限。这对于理解用户的访问能力和管理用户权限至关重要。 1. 使用 MongoDB Shell 查看角色和权限 1.1 查看当前数据库用户 要查看当前数据库中的所有用户及其角色&#xff0c;可以使用以下命令&#x…

带你0到1之QT编程:二十二、QChart类图表及折线图、直方图、饼图的三大可视化图表实战!

此为QT编程的第二十二谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01;…

达梦8-DTS迁移测试-从Oracle迁移到达梦

1、目的 将Oracle数据库的SCOTT用户下的表迁移到达梦8。 2、数据库信息 2.1 Oracle端 操作系统 Redhat 7.5 数据库架构 单机 数据库版本 Oracle 19c 待迁移数据库名 prodpdb 待迁移的对象 SCOTT IP/端口 192.168.6.121:1521 用户名/密码 scott/tiger 字符集编…