这个基于SSM框架的企业员工抽奖管理系统,是我在2026年完成的一个毕业设计项目。作为一个完整的Java Web应用,它解决了传统企业抽奖活动中存在的效率低下、公平性难以保障等痛点问题。系统采用B/S架构,整合了Spring、SpringMVC和MyBatis三大主流框架,实现了从员工管理、奖品配置到抽奖执行和结果统计的全流程数字化管理。
在实际开发过程中,我发现很多企业还在使用Excel表格甚至纸质抽奖券的方式进行员工抽奖活动,不仅耗时耗力,而且缺乏透明度和可追溯性。这个系统正是为了解决这些问题而设计的,它能够确保每次抽奖活动的公平性,同时为企业提供详细的数据分析支持。
选择SSM框架组合是经过深思熟虑的决策。Spring框架提供了强大的IoC容器和AOP支持,SpringMVC作为表现层框架能够很好地处理Web请求,而MyBatis则简化了数据库操作。这个组合相比传统的SSH框架更加轻量级,更适合中小型企业的应用场景。
数据库选用MySQL 5.7版本,主要考虑到:
前端技术栈采用JSP+Bootstrap+Vue.js的组合:
系统主要分为四个核心模块:
员工管理模块
奖品管理模块
奖券管理模块
中奖管理模块
抽奖系统的核心在于随机算法的公平性和效率。我最终采用了加权随机算法结合Redis分布式锁的方案:
java复制public class WeightedRandomAlgorithm {
// 奖品列表及其权重
private List<Prize> prizes;
public Prize draw() {
// 计算总权重
double totalWeight = prizes.stream().mapToDouble(Prize::getWeight).sum();
// 生成随机数
double random = Math.random() * totalWeight;
// 根据权重选择奖品
double currentWeight = 0;
for (Prize prize : prizes) {
currentWeight += prize.getWeight();
if (random <= currentWeight) {
return prize;
}
}
return null;
}
}
为了保证高并发下的线程安全,我引入了Redis分布式锁:
java复制public boolean tryLock(String lockKey, String requestId, int expireTime) {
Jedis jedis = jedisPool.getResource();
try {
String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
return "OK".equals(result);
} finally {
jedis.close();
}
}
抽奖过程涉及多个数据表的原子性操作,包括:
我使用Spring的声明式事务管理来确保数据一致性:
java复制@Service
public class LotteryServiceImpl implements LotteryService {
@Transactional(rollbackFor = Exception.class)
public LotteryResult drawLottery(String employeeId) {
// 1. 检查员工资格
// 2. 执行抽奖算法
// 3. 扣减奖品库存
// 4. 生成中奖记录
// 5. 更新奖券状态
}
}
为了让抽奖结果能够实时展示,我采用了WebSocket技术:
java复制@ServerEndpoint("/lottery/result")
public class LotteryResultEndpoint {
private static Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
}
@OnClose
public void onClose(Session session) {
sessions.remove(session);
}
public static void broadcast(String message) {
for (Session session : sessions) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
员工表(employee)
sql复制CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`department` varchar(50) NOT NULL,
`position` varchar(50) DEFAULT NULL,
`join_date` date DEFAULT NULL,
`status` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`),
KEY `idx_department` (`department`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
奖品表(prize)
sql复制CREATE TABLE `prize` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`category` varchar(50) NOT NULL,
`stock` int(11) NOT NULL DEFAULT '0',
`weight` int(11) NOT NULL DEFAULT '1',
`image_url` varchar(255) DEFAULT NULL,
`description` text,
`status` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`),
KEY `idx_category` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
奖券表(ticket)
sql复制CREATE TABLE `ticket` (
`id` varchar(32) NOT NULL,
`employee_id` int(11) NOT NULL,
`generate_time` datetime NOT NULL,
`expire_time` datetime DEFAULT NULL,
`status` tinyint(1) DEFAULT '0' COMMENT '0-未使用 1-已使用 2-已过期',
PRIMARY KEY (`id`),
KEY `idx_employee` (`employee_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
中奖记录表(winning_record)
sql复制CREATE TABLE `winning_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`employee_id` int(11) NOT NULL,
`prize_id` int(11) NOT NULL,
`ticket_id` varchar(32) NOT NULL,
`win_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_employee` (`employee_id`),
KEY `idx_prize` (`prize_id`),
KEY `idx_time` (`win_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
为了提高查询性能,我在以下字段上建立了索引:
bash复制# 下载JDK 1.8
wget https://download.oracle.com/otn/java/jdk/8u301-b09/d3c52aa6bfa54d3ca74e617f18309292/jdk-8u301-linux-x64.tar.gz
# 解压并配置环境变量
tar -zxvf jdk-8u301-linux-x64.tar.gz -C /usr/local/
echo 'export JAVA_HOME=/usr/local/jdk1.8.0_301' >> /etc/profile
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
source /etc/profile
bash复制# 下载Tomcat 7.0
wget https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.109/bin/apache-tomcat-7.0.109.tar.gz
# 解压并启动
tar -zxvf apache-tomcat-7.0.109.tar.gz -C /usr/local/
/usr/local/apache-tomcat-7.0.109/bin/startup.sh
bash复制# 安装MySQL 5.7
sudo apt-get install mysql-server-5.7
# 创建数据库用户
mysql -u root -p
CREATE DATABASE lottery_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'lottery'@'%' IDENTIFIED BY 'Lottery@123';
GRANT ALL PRIVILEGES ON lottery_system.* TO 'lottery'@'%';
FLUSH PRIVILEGES;
使用JMeter对系统进行了压力测试,主要测试场景:
单用户抽奖响应时间
并发抽奖测试(100用户)
数据库查询性能
测试环境配置:
并发抽奖导致的超发问题
现象:在高并发场景下,热门奖品会出现超发现象
解决方案:
抽奖结果实时展示延迟
现象:抽奖结果在前端展示有较明显延迟
解决方案:
奖券生成算法性能瓶颈
现象:批量生成10万张奖券时耗时过长
优化方案:
java复制public void batchInsertTickets(List<Ticket> tickets) {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
TicketMapper mapper = sqlSession.getMapper(TicketMapper.class);
for (Ticket ticket : tickets) {
mapper.insert(ticket);
}
sqlSession.commit();
} finally {
sqlSession.close();
}
}
java复制@Service
public class LotteryService {
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void executeLottery() {
// 主事务方法
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void recordWinning() {
// 需要独立事务的方法
}
}
在实际使用过程中,我发现系统还可以在以下几个方面进行扩展:
多级奖品池设计
员工积分系统
移动端适配
数据分析增强
安全增强
这个抽奖管理系统从设计到实现历时3个月,期间遇到了不少技术挑战,但最终都找到了合适的解决方案。通过这个项目,我深刻体会到企业级应用开发需要考虑的不仅仅是功能实现,还有性能、安全、可维护性等多方面因素。特别是在处理高并发场景时,合理的架构设计和优化策略至关重要。