news 2026/10/6 8:20:03

SSM+MySQL线上会议管理系统毕业设计:时间冲突检测与权限控制实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SSM+MySQL线上会议管理系统毕业设计:时间冲突检测与权限控制实战

简介:这份毕业设计资源包围绕中小型公司线上会议预约场景展开,采用Java MVC模式与MySQL关系型数据库,构建了前端加后端的会议管理系统,适合计算机相关专业学生作为毕业设计参考,也适合需要SSM实战练手的开发者。系统涵盖部门管理、会议室管理、公告管理与预约管理等核心模块,并配有注册登录、后台管理等辅助功能,论文部分包含系统实现与测试章节,涉及开发环境、首页、预约、用户、公告及登录注册等测试用例。资源包共2000个文件,约150.8MB,以js脚本、json配置、jsp页面、css样式、java源码、html页面和xml配置为主,另含sql建库脚本与docx论文文档,结构完整便于按模块查阅。目前已有108人学习下载,读者可获取源码、数据库脚本、论文与演示视频,快速理解SSM项目分层与预约业务实现思路。

1. 线上会议管理系统:从 SSM 到 MySQL 的毕业设计落地路径

线上会议管理系统这个题目,在计算机毕业设计里属于典型的“业务不复杂、但技术栈必须完整”的类型。它要解决的核心问题很具体:用户注册登录后能创建会议、邀请参会人、管理会议状态,管理员能审核用户和会议。听起来像是一个 CRUD 项目,但真正动手做的时候,你会发现权限模型、时间冲突检测、状态流转这三块才是拉开差距的地方。SSM 框架配合 MySQL 是这类系统最常见的组合,Spring 负责业务对象管理和事务,SpringMVC 处理请求路由和参数绑定,MyBatis 做数据持久化。适合谁做?适合已经学过 JavaWeb、能写基本 Servlet 和 JSP、但对框架整合还没有完整跑通过一遍的本科生。这篇文章不讲空泛的架构图,而是把从建库到接口联调的完整路径拆开,让你能照着复现一个能跑、能演示、能写进论文的系统。

2. SSM 整合与 MySQL 建库:先把地基打对

2.1 为什么选 SSM 而不是 SpringBoot

很多同学一上来就想用 SpringBoot,觉得省事。但毕业设计答辩时,老师往往会问“Spring 的 IOC 和 AOP 在这个项目里怎么体现的”。如果你用 SpringBoot,自动配置把很多东西藏起来了,你反而说不清楚。SSM 虽然配置多,但每一步都是显式的,你亲手写过applicationContext.xml里的数据源、事务管理器、MyBatis 的SqlSessionFactory,答辩时就能指着配置文件讲清楚依赖注入和事务边界的实际位置。

另一个现实原因是:SSM 的教程和现成代码模板在各类资源站上最多,遇到问题容易搜到答案。MySQL 版本选择上,5.7 和 8.0 都可以,但 8.0 的驱动类名和连接 URL 参数有变化,很多老教程用的是 5.7 的写法,直接抄会报Communications link failure。我一般建议用 MySQL 5.7.44 或者 8.0.33,这两个版本在 Windows 和 Linux 上的安装包都容易找,社区问答也最丰富。

2.2 数据库表设计:五张核心表就够

线上会议管理系统的表不用多,但字段要想清楚。下面是我实际用过的建表语句,直接可以在 MySQL 里执行:

-- 用户表:区分普通用户和管理员 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '登录名', `password` varchar(64) NOT NULL COMMENT 'MD5加密存储', `real_name` varchar(50) DEFAULT NULL, `role` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-普通用户 1-管理员', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1-正常 0-禁用', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 会议表:核心业务表 CREATE TABLE `meeting` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL, `room_id` int(11) NOT NULL COMMENT '关联会议室', `organizer_id` int(11) NOT NULL COMMENT '发起人', `start_time` datetime NOT NULL, `end_time` datetime NOT NULL, `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-待审核 1-已通过 2-已拒绝 3-已结束', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_room_time` (`room_id`,`start_time`,`end_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 会议室表 CREATE TABLE `room` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `capacity` int(11) NOT NULL DEFAULT '10', `location` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 参会人关联表 CREATE TABLE `meeting_attendee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `meeting_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `join_status` tinyint(1) DEFAULT '0' COMMENT '0-未确认 1-已确认', PRIMARY KEY (`id`), UNIQUE KEY `uk_meeting_user` (`meeting_id`,`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 操作日志表:答辩加分项 CREATE TABLE `operation_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `action` varchar(200) DEFAULT NULL, `ip` varchar(50) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

meeting表上的idx_room_time联合索引是关键。后面做时间冲突检测时,查询条件是room_id = ? AND start_time < ? AND end_time > ?,没有这个索引,数据量一上来就会全表扫描。meeting_attendee表的唯一键防止同一个人被重复邀请。operation_log表不是必须的,但加上之后,答辩时演示“管理员查看操作记录”会显得系统更完整。

2.3 SSM 配置文件的最小可用集合

SSM 整合需要四个配置文件:web.xml、spring-mvc.xml、applicationContext.xml、mybatis-config.xml,外加一个jdbc.properties。这里不贴全部内容,只说三个最容易配错的地方。

第一,web.xml里ContextLoaderListener和DispatcherServlet的contextConfigLocation要分开。前者加载applicationContext.xml(Service 和 DAO 层),后者加载spring-mvc.xml(Controller 层)。如果都塞进一个文件,事务注解会失效,因为 Spring 容器和 SpringMVC 容器各扫各的包,事务代理对象在 Controller 里拿不到。

第二,applicationContext.xml里扫描 Service 包时,要排除 Controller 注解:

<context:component-scan base-package="com.example.service"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

第三,MyBatis 的mapperLocations路径要用classpath*:开头,否则打包成 war 之后 XML 映射文件可能找不到。

提示:MySQL 8.0 的驱动类是com.mysql.cj.jdbc.Driver,URL 要加serverTimezone=Asia/Shanghai,否则插入 datetime 字段会报时区错误。

3. 会议创建与时间冲突检测:业务逻辑的核心

3.1 时间冲突检测的 SQL 写法

这是整个系统里唯一需要动脑子写 SQL 的地方。判断一个会议室在某个时间段是否已被占用,逻辑是:存在一条记录,它的开始时间早于新会议的结束时间,且结束时间晚于新会议的开始时间。用 SQL 表达:

SELECT COUNT(*) FROM meeting WHERE room_id = #{roomId} AND status IN (0, 1) AND start_time < #{endTime} AND end_time > #{startTime}

注意status IN (0, 1)只检查待审核和已通过的会议,已拒绝和已结束的不算占用。这个条件如果漏了,已结束的会议会一直阻塞新会议创建,用户会以为系统坏了。

对应的 MyBatis Mapper 接口和 XML:

// MeetingMapper.java int countConflict(@Param("roomId") Integer roomId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);
<!-- MeetingMapper.xml --> <select id="countConflict" resultType="int"> SELECT COUNT(*) FROM meeting WHERE room_id = #{roomId} AND status IN (0, 1) AND start_time &lt; #{endTime} AND end_time &gt; #{startTime} </select>

Service 层调用时,如果返回值大于 0,就抛出自定义异常TimeConflictException,Controller 捕获后返回“该时间段会议室已被占用”的提示。

3.2 会议状态流转与权限控制

会议状态有四个:待审核、已通过、已拒绝、已结束。状态流转规则是:普通用户创建后为待审核;管理员审核通过变为已通过,拒绝变为已拒绝;已通过的会议在结束时间过后由定时任务或手动操作变为已结束。这里有一个容易翻车的地方:普通用户不能直接修改status字段。如果 Controller 接收前端传来的完整 Meeting 对象直接 update,恶意用户可以把 status 改成 1 绕过审核。

正确做法是在 Service 层做字段级控制:

public void updateMeeting(Meeting meeting, Integer currentUserId, boolean isAdmin) { Meeting existing = meetingMapper.selectById(meeting.getId()); if (!isAdmin && !existing.getOrganizerId().equals(currentUserId)) { throw new PermissionDeniedException("无权修改此会议"); } if (!isAdmin) { // 普通用户只能改标题、时间、参会人,不能改状态 existing.setTitle(meeting.getTitle()); existing.setStartTime(meeting.getStartTime()); existing.setEndTime(meeting.getEndTime()); meetingMapper.updateById(existing); } else { meetingMapper.updateById(meeting); } }

这段代码的逻辑是:先查原记录,判断当前用户是否有权限;普通用户只允许更新部分字段,管理员才能全量更新。参数currentUserId从 Session 中获取,不要从前端传,否则可以伪造。

3.3 参会人邀请的批量插入

邀请参会人时,前端传过来一个userId列表,后端需要批量插入meeting_attendee表。用 MyBatis 的foreach标签:

<insert id="batchInsertAttendees"> INSERT INTO meeting_attendee (meeting_id, user_id, join_status) VALUES <foreach collection="list" item="item" separator=","> (#{item.meetingId}, #{item.userId}, 0) </foreach> </insert>

参数说明:collection="list"对应 Mapper 接口中List<MeetingAttendee>类型的参数。如果接口方法有多个参数,需要用@Param指定名称,collection也要改成对应的名称。批量插入时,如果列表中有一条重复的(meeting_id, user_id),整个插入会失败并回滚。所以 Service 层要先查一遍已存在的参会人,过滤掉重复的再插入。

4. 避坑与排查:那些答辩前夜才发现的错误

4.1 中文乱码从数据库到前端全链路

现象:会议标题在数据库里看是正常的,但页面上显示问号。原因:MySQL 连接 URL 没有指定字符集,或者 Tomcat 的server.xml里 Connector 没有加URIEncoding="UTF-8"。解决:JDBC URL 加上useUnicode=true&characterEncoding=utf8,Tomcat Connector 加上URIEncoding="UTF-8",数据库和表的字符集统一用utf8mb4。三个地方缺一不可。

4.2 事务不生效导致数据不一致

现象:创建会议时,会议记录插入成功,但参会人插入失败,数据库里留下了一条没有参会人的会议。原因:Service 类的方法上没有加@Transactional,或者加了但方法不是 public,或者异常被 catch 了没有重新抛出。解决:在 Service 类的创建方法上加@Transactional(rollbackFor = Exception.class),确保任何异常都触发回滚。注意rollbackFor要显式写Exception.class,因为 Spring 默认只对RuntimeException回滚。

4.3 MyBatis 的#{}和${}用混

现象:按标题模糊查询时,输入%导致查出全部记录。原因:XML 里用了${}拼接,而不是#{}预编译。解决:模糊查询用CONCAT('%', #{keyword}, '%'),不要用'%${keyword}%'。${}只用在动态表名或排序字段这种无法预编译的场景,并且要在 Java 层做白名单校验。

4.4 时间字段前后端格式不一致

现象:前端传2024-01-01 10:00:00,后端接收时报Cannot deserialize value of type java.util.Date。原因:SpringMVC 默认不支持这种格式的字符串转 Date。解决:在 Controller 的日期参数上加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss"),或者在spring-mvc.xml里注册全局的FormattingConversionServiceFactoryBean。如果用的是@RequestBody接收 JSON,则需要在实体类的日期字段上加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")。

4.5 部署到 Tomcat 后 404

现象:本地 Eclipse 里跑得好好的,导出 war 包放到 Tomcat 的webapps目录下启动,访问就是 404。原因:web.xml里DispatcherServlet的url-pattern配的是/,但 SpringMVC 的视图解析器前缀写的是/WEB-INF/jsp/,而 JSP 文件没有一起打包进去。解决:检查 war 包里的目录结构,确保 JSP 文件在WEB-INF/jsp/下。另一个常见原因是applicationContext.xml里的包扫描路径写的是com.example,但实际代码包名是cn.example,导致 Bean 没有创建。

5. 从能跑到能演示:三个提升完成度的技巧

5.1 用拦截器做登录校验和操作日志

登录校验不要在每个 Controller 方法里写if (session.getAttribute("user") == null)。写一个HandlerInterceptor,在preHandle里统一判断,然后在spring-mvc.xml里配置拦截路径和排除路径。操作日志也可以在拦截器里做:postHandle中拿到请求的 URL 和当前用户,异步插入operation_log表。这样答辩时演示“管理员查看操作日志”就有真实数据,而不是手动往数据库里塞几条。

public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); // 登录页和静态资源放行 if (uri.contains("/login") || uri.contains("/static/")) { return true; } Object user = request.getSession().getAttribute("currentUser"); if (user == null) { response.sendRedirect(request.getContextPath() + "/login"); return false; } return true; } }

参数说明:preHandle返回false时,请求会被中断,后续的 Controller 不会执行。response.sendRedirect的路径要加上request.getContextPath(),否则部署到非根路径下会跳转错误。

5.2 会议列表分页用 PageHelper

不要自己写LIMIT和COUNT两条 SQL,容易算错总页数。引入 PageHelper 插件,在 MyBatis 配置里加一行:

<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="helperDialect" value="mysql"/> </plugin> </plugins>

然后在 Service 里调用PageHelper.startPage(pageNum, pageSize),紧接着执行查询,返回的List会被自动包装成PageInfo对象,里面包含总记录数、总页数、当前页数据。注意startPage之后必须紧跟查询语句,中间不能插入其他数据库操作,否则分页参数会作用到错误的查询上。

5.3 演示视频的录制节奏

如果毕设要求提交演示视频,不要从头到尾录一遍操作。按这个顺序录:先展示登录和角色区分(普通用户和管理员看到不同菜单),再展示创建会议和时间冲突提示,然后展示管理员审核和参会人确认,最后展示操作日志和数据库表数据。每个环节控制在 30 秒以内,总时长 3 到 5 分钟。录制前把数据库里的测试数据准备好,避免现场创建时因为时间冲突反复失败。我自己的习惯是提前跑一遍完整流程,把每一步的点击位置记在纸上,录的时候照着点,一次过。

希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 8:18:05

WinForm酒店管理系统开发实战:数据库设计、CRUD与部署避坑指南

简介&#xff1a;一套面向酒店管理场景的C# WinFormSQLServer毕业设计源码包&#xff0c;适合计算机相关专业的在校学生、老师及企业员工用于课程设计、项目初期演示或二次开发。项目代码通过完整测试&#xff0c;具备房态管理、预订登记、结账退房等典型业务模块&#xff0c;并…

作者头像 李华
网站建设 2026/10/6 8:17:47

基于SSM+MySQL的文物管理系统:从环境搭建到答辩演示全流程解析

简介&#xff1a;一套基于SSM框架与MySQL数据库的文物管理系统毕业设计资料包&#xff0c;适合计算机专业学生用于课程设计、毕业设计以及项目实战参考。系统采用浏览器/服务器结构&#xff0c;使用JSP动态页面技术&#xff0c;后台选用MySQL数据库&#xff0c;覆盖文物分类、文…

作者头像 李华
网站建设 2026/10/6 8:17:46

从源码部署到二次开发:一套旗舰版CRM系统的完整落地指南

简介&#xff1a;这是一套功能完整的旗舰版CRM客户关系管理系统源码&#xff0c;适合中小企业及具备二次开发能力的PHP开发者使用&#xff0c;用于高效管理客户、销售、采购、库存、售后等全流程业务。资源共1903个文件&#xff0c;以PHP后端逻辑、HTML前端页面、JavaScript交互…

作者头像 李华
网站建设 2026/10/6 8:17:45

PHP开源CRM系统源码解析:线索池、工作流与二次开发实战

简介&#xff1a;这款旗舰版CRM客户管理系统源码&#xff0c;面向需要规范客户全流程管理的中小企业及二次开发人员。系统完整覆盖线索、客户、商机、合同、财务、销售、采购、库存、产品、任务、日程、知识、日志、站内信、营销等核心业务模块&#xff0c;支持员工限时限额领取…

作者头像 李华
网站建设 2026/10/6 8:16:51

学生资助小程序开发实战:SSM+微信原生+MySQL全流程落地

简介&#xff1a;本资源是一套完整的毕业设计项目——学生资助在线管理小程序&#xff0c;面向计算机专业本科生及Java全栈初学者&#xff0c;解决高校学生资助业务中信息分散、流程低效、角色协同不足等实际问题。系统采用微信小程序前端&#xff08;含136个Vue组件&#xff0…

作者头像 李华
网站建设 2026/10/6 8:14:38

ST-GCN骨骼动作识别实战:图卷积原理、PyTorch实现与避坑指南

简介&#xff1a;这是一份面向毕业设计、期末大作业及课程设计的Python实战项目&#xff0c;基于时空图卷积网络&#xff08;ST-GCN&#xff09;实现骨骼动作识别。项目代码包含详细注释&#xff0c;从数据处理、模型构建到训练推理均有清晰呈现&#xff0c;适合具备一定Python…

作者头像 李华