ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SSM+Vue学生选课系统开发实战

SSM+Vue学生选课系统开发实战 1. 项目概述这个基于SSMVue的学生选课系统是一个典型的校园信息化解决方案它采用了当前主流的Java全栈技术架构。作为一名有10年开发经验的工程师我认为这类系统在实际教学管理中具有极高的实用价值。系统通过前后端分离的设计实现了学生选课、教师排课、管理员管理等核心功能模块。从技术架构来看后端采用Spring BootMyBatis Plus的组合前端使用Vue.js框架这种技术选型在当前企业级应用开发中非常流行。Spring Boot的自动配置特性大大简化了项目搭建过程而Vue的响应式特性则让前端开发更加高效。数据库选用MySQL保证了系统的稳定性和性能。2. 系统架构设计2.1 MVC分层架构系统采用标准的MVC设计模式将应用分为以下几个层次表现层(View)使用Vue.js构建的用户界面负责数据展示和用户交互控制层(Controller)Spring MVC的Controller接收前端请求协调各组件工作服务层(Service)实现核心业务逻辑处理复杂的业务规则持久层(Dao)MyBatis Plus负责数据库操作简化了SQL编写这种分层设计使得系统各组件职责明确便于维护和扩展。在实际开发中我通常会为每个层次建立独立的package如com.xxx.controller、com.xxx.service等保持代码结构清晰。2.2 前后端分离架构系统采用B/S架构前后端完全分离前端Vue.js Element UI构建的单页应用后端Spring Boot提供的RESTful API接口通信通过HTTP/HTTPS协议数据格式为JSON这种架构的优势在于前后端可以并行开发提高开发效率前端可以使用更专业的技术栈提升用户体验后端接口可以服务于多种客户端(Web、App等)在实际部署时建议将前端静态资源部署在Nginx服务器上后端服务部署在Tomcat或Jetty容器中。3. 技术栈详解3.1 后端技术栈3.1.1 Spring Boot框架Spring Boot是系统的核心框架它提供了以下关键特性自动配置根据项目依赖自动配置Spring应用起步依赖简化Maven/Gradle配置内嵌容器默认集成Tomcat无需额外部署健康检查提供/actuator端点监控应用状态在项目中我们通过SpringBootApplication注解启动应用这个注解实际上包含了Configuration、EnableAutoConfiguration和ComponentScan三个注解的功能。3.1.2 MyBatis PlusMyBatis Plus是MyBatis的增强工具它提供了以下便利功能通用Mapper内置常用的CRUD方法无需编写XML条件构造器通过Lambda表达式构建复杂查询条件分页插件简化分页查询实现代码生成器自动生成Entity、Mapper、Service等代码在实际开发中我通常会创建一个BaseService抽象类封装常用的增删改查方法其他Service继承它即可获得基础CRUD能力。3.2 前端技术栈3.2.1 Vue.js框架Vue.js作为前端框架主要优势包括响应式数据绑定数据变化自动更新视图组件化开发将UI拆分为独立可复用的组件虚拟DOM高效更新页面提升性能丰富的生态系统Vue Router、Vuex等配套工具在项目中我们使用Vue CLI搭建项目骨架通过vue-router实现前端路由vuex管理全局状态。3.2.2 Element UI组件库Element UI是基于Vue的UI组件库它提供了丰富的UI组件表格、表单、弹窗等常用组件响应式布局适配不同屏幕尺寸主题定制可以灵活修改样式主题国际化支持支持多语言切换在实际开发中建议按需引入Element UI组件避免打包体积过大。4. 核心功能实现4.1 用户认证模块4.1.1 登录注册实现系统采用JWT(JSON Web Token)进行身份认证主要流程如下用户提交用户名密码服务端验证通过后生成JWT令牌令牌返回给客户端存储后续请求携带令牌进行鉴权关键代码示例// 生成JWT令牌 public String generateToken(UserDetails userDetails) { MapString, Object claims new HashMap(); return Jwts.builder() .setClaims(claims) .setSubject(userDetails.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRATION_TIME)) .signWith(SignatureAlgorithm.HS512, SECRET) .compact(); } // 验证JWT令牌 public Boolean validateToken(String token, UserDetails userDetails) { final String username extractUsername(token); return (username.equals(userDetails.getUsername()) !isTokenExpired(token)); }4.1.2 权限控制系统使用基于角色的访问控制(RBAC)模型定义角色学生、教师、管理员分配权限不同角色有不同的操作权限注解控制使用PreAuthorize注解进行方法级权限控制示例PreAuthorize(hasRole(ADMIN)) PostMapping(/users) public Result addUser(RequestBody User user) { // 添加用户逻辑 }4.2 选课功能模块4.2.1 课程查询学生可以按多种条件查询可选课程按课程名称模糊查询按教师姓名查询按上课时间筛选按学分范围筛选后端实现使用MyBatis Plus的条件构造器public PageCourse queryCourses(CourseQuery query, Pageable pageable) { QueryWrapperCourse wrapper new QueryWrapper(); if (StringUtils.isNotBlank(query.getCourseName())) { wrapper.like(course_name, query.getCourseName()); } if (StringUtils.isNotBlank(query.getTeacherName())) { wrapper.eq(teacher_name, query.getTeacherName()); } if (query.getCredit() ! null) { wrapper.eq(credit, query.getCredit()); } return courseMapper.selectPage(new Page(pageable.getPageNumber(), pageable.getPageSize()), wrapper); }4.2.2 选课逻辑选课业务逻辑需要考虑以下约束条件课程容量限制时间冲突检查先修课程要求学分上限控制实现代码示例public Result selectCourse(Long studentId, Long courseId) { // 检查课程是否存在且可选 Course course courseMapper.selectById(courseId); if (course null || !course.getStatus().equals(CourseStatus.OPEN)) { return Result.error(课程不可选); } // 检查是否已选过该课程 if (selectionMapper.existsSelection(studentId, courseId)) { return Result.error(已选过该课程); } // 检查时间冲突 if (selectionMapper.hasTimeConflict(studentId, course.getSchedule())) { return Result.error(时间冲突); } // 检查学分上限 int currentCredits selectionMapper.sumCredits(studentId); if (currentCredits course.getCredit() MAX_CREDITS) { return Result.error(超过学分上限); } // 执行选课 CourseSelection selection new CourseSelection(studentId, courseId); selectionMapper.insert(selection); // 更新课程已选人数 course.setSelectedNumber(course.getSelectedNumber() 1); courseMapper.updateById(course); return Result.success(选课成功); }5. 数据库设计5.1 主要表结构5.1.1 用户表(user)字段名类型描述idbigint主键IDusernamevarchar(50)用户名passwordvarchar(100)密码(加密存储)real_namevarchar(50)真实姓名rolevarchar(20)角色(student/teacher/admin)statustinyint状态(0-禁用,1-启用)create_timedatetime创建时间5.1.2 课程表(course)字段名类型描述idbigint主键IDcourse_namevarchar(100)课程名称teacher_idbigint授课教师IDcreditint学分max_numberint最大选课人数selected_numberint已选人数schedulevarchar(100)上课时间安排classroomvarchar(50)教室statusvarchar(20)状态(OPEN/CLOSED)descriptiontext课程描述5.1.3 选课记录表(course_selection)字段名类型描述idbigint主键IDstudent_idbigint学生IDcourse_idbigint课程IDselection_timedatetime选课时间scoredecimal(5,2)成绩5.2 索引优化建议为了提高查询性能建议在以下字段上创建索引user表的username字段(唯一索引)course表的teacher_id字段course_selection表的student_id和course_id字段(复合索引)SQL示例CREATE INDEX idx_course_teacher ON course(teacher_id); CREATE INDEX idx_selection_stu_course ON course_selection(student_id, course_id);6. 系统部署指南6.1 开发环境搭建6.1.1 后端环境JDK 1.8Maven 3.6MySQL 5.7IDE(IntelliJ IDEA或Eclipse)配置步骤导入Maven项目修改application.yml中的数据库配置执行src/main/resources/sql下的建表脚本启动Spring Boot应用6.1.2 前端环境Node.js 12npm或yarnVue CLI 4配置步骤安装依赖npm install修改src/config.js中的API基础地址启动开发服务器npm run serve构建生产版本npm run build6.2 生产环境部署6.2.1 后端部署推荐使用Docker容器化部署构建Docker镜像mvn clean package docker build -t course-system .运行容器docker run -d -p 8080:8080 \ -e SPRING_DATASOURCE_URLjdbc:mysql://mysql-server:3306/course_db \ -e SPRING_DATASOURCE_USERNAMEroot \ -e SPRING_DATASOURCE_PASSWORDyourpassword \ course-system6.2.2 前端部署将构建的静态文件部署到Nginx修改Nginx配置server { listen 80; server_name yourdomain.com; location / { root /path/to/dist; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }重启Nginx服务7. 常见问题与解决方案7.1 开发阶段问题7.1.1 跨域问题现象前端访问后端API时出现CORS错误解决方案后端添加CORS配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(*) .allowedHeaders(*); } }或者使用Nginx反向代理将前后端放在同一域名下7.1.2 时区问题现象数据库中的时间与Java应用中的时间不一致解决方案MySQL连接字符串添加时区参数spring: datasource: url: jdbc:mysql://localhost:3306/course_db?serverTimezoneAsia/Shanghai应用启动时设置默认时区PostConstruct void started() { TimeZone.setDefault(TimeZone.getTimeZone(Asia/Shanghai)); }7.2 运行阶段问题7.2.1 性能优化当系统用户量增大时可能会遇到性能瓶颈建议数据库层面添加合适的索引优化慢查询考虑读写分离应用层面启用二级缓存(Redis)异步处理耗时操作分页查询大数据集JVM调优调整堆内存大小选择合适的GC算法7.2.2 安全加固系统安全措施建议密码加密存储使用BCryptPasswordEncoder接口防刷添加限流措施XSS防护前端过滤特殊字符后端校验输入SQL注入防护使用预编译语句MyBatis使用#{}而非${}8. 项目扩展建议8.1 功能扩展微信小程序端开发配套小程序方便学生手机选课课表导出支持将课表导出为PDF或日历格式选课冲突自动检测图形化展示时间冲突教师评价系统学生对课程和教师进行评价8.2 技术升级微服务化将系统拆分为用户服务、课程服务、选课服务等微服务引入消息队列使用RabbitMQ处理选课高峰期的并发请求分布式缓存使用Redis缓存热门课程信息全链路监控集成PrometheusGrafana监控系统性能在实际开发中建议根据项目规模和团队技术能力选择合适的扩展方向。对于小型团队可以先完善核心功能再逐步扩展对于大型项目可以考虑从一开始就采用更先进的架构设计。
返回列表