数据库脚本:
/** * 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);
}









