尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

考研资讯管理系统Java毕设全攻略:设计、数据库与实现要点

考研资讯管理系统Java毕设全攻略:设计、数据库与实现要点 1. 项目到底在做什么考研资讯管理系统的核心需求先把话说在前面计算机毕设选考研资讯管理系统这个题目属于典型的看起来简单、做起来有讲究的项目。你要是第一次做Java Web方向的毕设这个题目非常合适——它不像电商系统那样动辄十几个模块也不像纯后台管理系统那样枯燥无味它有一个很明确的业务场景帮考研学生集中获取院校信息、专业目录、考研资讯、复习资料同时给管理员一个后台来维护这些内容。从毕设答辩的角度看这类系统的优势是业务逻辑清晰、技术栈主流、数据库设计有看点。评委会问你这个系统解决什么问题你可以理直气壮地说考研学生面临的信息分散问题。院校官网、研招网、论坛、公众号信息各在一处学生需要自己整理对比效率低且容易遗漏。你这个系统把资讯、院校、专业、分数线、经验帖集中在一个平台里按类别、按地区、按年份检索这就是它存在的意义。再说说技术选型。标题里明确写了Java所以主语言就是Java。常见的搭配有两种JSP Servlet MySQL经典老组合适合对框架不熟、想稳扎稳打完成毕设的同学。Spring Boot MyBatis/Spring Data JPA MySQL目前企业主流也是毕设加分项但需要你理解自动配置、依赖注入这些概念。我个人建议除非你时间特别紧否则优先选Spring Boot。原因很简单Spring Boot帮你省掉了大量XML配置起步快而且答辩时提到使用Spring Boot简化了项目搭建与配置这句话本身就是亮点。至于前端不必过度设计HTML CSS Bootstrap jQuery够了想锦上添花可以引入Vue但别为了炫技把复杂度拉高毕设首先保证的是能完整跑通、逻辑自洽。这个系统的用户角色至少要有三种普通游客未登录用户、登录学生用户、后台管理员。游客可以浏览公开资讯学生可以收藏资讯、查看院校详情、在论坛板块发帖回帖管理员负责发布资讯、管理用户、审核帖子、维护院校和专业数据。有些同学会根据学校要求加入教师角色来审核帖子不是不行但核心三角色已经足够支撑一套完整的毕设故事。下面我从需求设计、数据库设计、代码实现到常见坑一条线讲透。这套逻辑同样适用于其他Java毕设题目你能学到的是如何把一个题目拆成可落地的系统。2. 功能模块怎么划分三角色、四板块一后台功能划分是毕设的第一道分水岭。很多同学上来就画用例图用例图画得满天飞最后代码写不完。我的原则是功能宁精勿杂每个功能都要能在答辩时演示出来。你吹了十个功能现场演示挂掉两个评委印象分直接崩你老老实实做八个个个个都能跑分数不会低。2.1 学生端前台功能设计前台是考研学生直接使用的页面核心是看、搜、存、问四个字。看资讯列表、资讯详情。资讯按分类区分比如备考经验、政策动态、院校通知、复试调剂。列表页要支持分页详情页要展示发布时间、来源、浏览量。浏览量这个字段千万别漏虽然实现起来就一个加加操作但有了它系统才有热点资讯的概念首页也可以做一个Top10热度排行评委看了会觉得你有产品思维。搜全局搜索和条件搜索。全局搜索就是输入关键词匹配标题和内容用LIKE查询即可。条件搜索主要针对院校库按地区省份筛选、按院校类型985/211/双一流/普通本科、按专业名称模糊查询。这里要注意院校和专业是两张表筛选逻辑要写清晰别搞出一堆冗余字段。存收藏功能。学生可以把感兴趣的院校或资讯加入收藏夹方便后续对比。收藏其实是一个中间表关联用户ID和业务ID业务类型区分是院校还是资讯。这类需求在数据库设计里很常见多做几个类似的中间表你对关系型数据建模的理解就会加深。问论坛互动。学生可以发帖提问标题正文分类标签可以回帖。回帖后楼主能看到提醒管理员能删除违规内容。论坛模块是展示事务操作的好地方发帖时写入主表和帖子摘要表可以用一个事务包起来答辩时能讲出东西来。2.2 管理员端后台功能设计后台功能围绕内容管理和用户管理两条线展开。资讯管理发布新资讯标题、封面图、分类、正文、是否置顶、编辑资讯、下线/删除资讯。正文建议用富文本编辑器比如wangEditor或者UEditor毕设用wangEditor居多因为轻量、中文文档全、导入简单。院校管理维护院校基础信息院校名称、地区、院校类型、简介、官网链接、维护专业目录专业名称、所属门类、考试科目、历年分数线。用户管理查看注册用户列表、禁用/启用用户、重置密码。这个是后台必备虽然业务逻辑简单但用户状态字段一定要留。评论与帖子管理审核帖子、删除违规评论。如果不想做审核流也可以简化成管理员直接删除但建议保留一个审核状态字段帖子发布后默认待审核管理员后台一键通过这又能成为答辩里的一个小亮点。2.3 公共模块和技术支撑点不管前台后台都需要以下公共模块用户认证与权限控制用Session保存登录状态用InterceptorSpring Boot里就是HandlerInterceptor做登录校验。后台接口额外校验角色管理员专属路径不允许普通用户访问。权限这块不用上Spring Security除非你时间充裕否则拦截器足够。统一异常处理用ControllerAdvice处理业务异常和未知异常返回友好的错误页面或JSON信息。这个在答辩时也是可以拿出来讲的点——我做了全局异常处理避免把堆栈信息直接抛给用户。密码安全明文存密码是大忌。至少用MD5加盐或者直接用BCrypt。推荐使用Spring Security Crypto里的BCryptPasswordEncoder几行代码就能集成。哪怕你的系统很简单这点做好了安全性能上升一个档次。分页前台列表页所有列表都做分页用PageHelper插件配MyBatis或者Spring Data JPA的Pageable都可以。分页做不好数据一多页面卡死演示直接尴尬。3. 数据库设计六张核心表加两张中间表数据库是毕设评委会重点看的东西表设计的好坏直接反映你有没有数据库功底。我不建议大家一上来就搞二十多张表考研资讯管理系统有个十张左右表就够了但每张表要设计得合理。3.1 核心六张表用户表t_user字段名类型说明idbigint主键自增usernamevarchar(50)用户名唯一passwordvarchar(100)加密后的密码nicknamevarchar(50)昵称emailvarchar(100)邮箱avatarvarchar(255)头像路径roletinyint角色1学生2管理员statustinyint状态0禁用1正常create_timedatetime注册时间注意role和status用tinyint别用varchar省空间且查询快。username加唯一索引防止重复注册。资讯表t_news/information核心字段id、title、category分类可以用字典类型存、cover_image、contenttext类型、source来源、views浏览量、is_top是否置顶、status草稿/发布/下线、create_by发布人、create_time、update_time。content用text类型注意在MyBatis的mapper里要加jdbcType处理不然某些数据库会报错。is_top和status都用tinyint查询置顶资讯时ORDER BY is_top DESC, create_time DESC。院校表t_university核心字段id、name、province、city、type985/211/双一流/普通、is_double_first_class可以并入type、introductiontext、website、logo、create_time。这里有个小技巧province用省份代码还是直接用省份名称毕设直接存名称就行省得再做字典表。但如果你想让系统更专业可以建一个省份字典表院校表存省份ID前端按ID关联显示。这个不强制看你自己时间。专业表t_major核心字段id、name、category学科门类、description。专业和院校是多对多关系所以需要一张中间表。帖子表t_post核心字段id、user_id发帖人、title、content、category、status待审核/已通过/已拒绝、view_count、reply_count、create_time、update_time。回复表t_reply核心字段id、post_id、user_id、content、create_time。3.2 关键中间表院校-专业关联表t_university_major字段就三个id、university_id、major_id。这张表用来存某个院校开设某个专业同时可以扩展字段比如考试科目、招生人数、复试分数线。很多毕设会把分数线单独建表我认为如果只是存一个数字放在关联表里加一个score_line字段更实用减少表数量。收藏表t_favorite字段id、user_id、target_id、type1资讯2院校、create_time。通过type字段区分收藏对象避免建两张收藏表。这是我比较推荐的做法一个中间表搞定多态关联。3.3 数据库设计中的注意点所有时间字段用datetime不要用timestamp某些数据库timestamp有2038年问题虽然毕设无所谓但好习惯要养成。每张表都要有create_time和update_time并且建议在插入和更新时自动维护。如果你用MyBatis可以在插入语句里写死NOW()如果用JPA可以用PrePersist和PreUpdate。外键约束建议不加逻辑外键就够了。加了外键在删除数据时会遇到各种约束问题毕设演示时操作流程很长容易卡住。我见过不少同学因为外键导致删不掉数据现场脸色都变了。为频繁查询的字段建索引资讯表title、院校表name、帖子表user_id这几个字段一定要加索引数据量大了之后效果明显。表名前缀统一比如都用t_开头。这会让你的SQL语句更清晰数据库设计文档也更好写。如果你需要画ER图PowerDesigner、Navicat、draw.io都可以毕设文档里的ER图建议用Navicat直接导出现有的数据库结构再微调一下比手画准确得多。4. 项目落地实操从创建工程到核心业务代码一条龙功能设计和数据库设计只是纸上谈兵接下来我用Spring Boot MyBatis的组合带你走一遍关键实现流程。这套流程是我自己带毕设学生走过多遍的照着做能少踩很多坑。4.1 第一步创建项目和目录结构用IDEA新建Spring Boot项目Java版本建议1.8或者11稳定且兼容性好。打包方式选Jar依赖勾选Spring Web、MyBatis Framework、MySQL Driver。后期如果需要校验功能再引入spring-boot-starter-validation。项目包结构按功能分包不要用三层架构的controller/service/mapper这样分。按模块分包的好处是你后期扩展功能不会手忙脚乱也更贴近实际企业项目规范。com.example.kaoyan ├── common // 通用类返回结果、异常、常量 │ ├── Result.java │ ├── ResultCode.java │ └── BusinessException.java ├── config // 配置类拦截器、跨域等 │ └── WebMvcConfig.java ├── controller // 控制器 │ ├── UserController.java │ ├── NewsController.java │ ├── UniversityController.java │ ├── PostController.java │ └── AdminController.java ├── service // 业务接口和实现 │ ├── UserService.java │ ├── impl/UserServiceImpl.java │ └── ... ├── mapper // MyBatis Mapper接口 │ ├── UserMapper.java │ └── ... ├── entity // 实体类 │ ├── User.java │ ├── News.java │ └── ... └── interceptor // 拦截器 └── LoginInterceptor.java4.2 第二步配置application.yml这里是最容易出问题的地方尤其是新手。一个典型配置如下server: port: 8080 servlet: context-path: / spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/kaoyan?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 servlet: multipart: max-file-size: 10MB max-request-size: 20MB thymeleaf: cache: false mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.kaoyan.entity configuration: map-underscore-to-camel-case: true重点注意serverTimezoneAsia/Shanghai一定要加否则连接MySQL 8.x时会报时区错误。useSSLfalse是因为本地开发一般没有配置SSL证书。map-underscore-to-camel-case设置为true后数据库字段create_time能自动映射到实体类的createTime省掉一大波别名字段。4.3 第三步实现登录和注册登录注册是整个系统的门神也是答辩时评委必然关注的点。我用一个简单但完整的方式实现。实体类User对应t_user表Service层写两个方法register和login。Service public class UserServiceImpl implements UserService { Autowired private UserMapper userMapper; Override public Result register(User user) { // 1. 校验用户名是否已存在 User existing userMapper.findByUsername(user.getUsername()); if (existing ! null) { return Result.error(用户名已存在); } // 2. 密码加密 String encodedPwd new BCryptPasswordEncoder().encode(user.getPassword()); user.setPassword(encodedPwd); user.setRole(1); user.setStatus(1); user.setCreateTime(new Date()); userMapper.insert(user); return Result.success(注册成功); } Override public Result login(String username, String password) { User user userMapper.findByUsername(username); if (user null) { return Result.error(用户不存在); } if (user.getStatus() 0) { return Result.error(账号已被禁用); } BCryptPasswordEncoder encoder new BCryptPasswordEncoder(); if (!encoder.matches(password, user.getPassword())) { return Result.error(密码错误); } // 登录成功保存用户信息到Session // 注意只存必要字段不要存密码 user.setPassword(null); return Result.success(user); } }这里有一个细节BCryptPasswordEncoder是Spring Security提供的虽然整体没引入Spring Security但只需要引入spring-security-crypto这个单独的依赖即可不会触发复杂的权限框架。dependency groupIdorg.springframework.security/groupId artifactIdspring-security-crypto/artifactId /dependencyController层PostMapping(/api/login) public Result login(RequestBody MapString, String params, HttpSession session) { String username params.get(username); String password params.get(password); Result result userService.login(username, password); if (result.isSuccess()) { session.setAttribute(loginUser, result.getData()); } return result; }用Session存登录状态在拦截器里判断public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session request.getSession(); Object loginUser session.getAttribute(loginUser); if (loginUser null) { // 判断是否为AJAX请求 String requestedWith request.getHeader(X-Requested-With); if (XMLHttpRequest.equals(requestedWith)) { response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\message\:\未登录\}); } else { response.sendRedirect(/login.html); } return false; } return true; } }注册的时候后端一定要做重复用户名校验和基础格式校验。很多同学只做前端校验后端不设防这点在答辩时被问到你们系统安全性如何就会卡壳。4.4 第四步资讯模块的实现资讯模块是前台最核心的内容板块。列表页按分类查询分页关键词搜索代码结构如下Mapper接口public interface NewsMapper { ListNews selectNewsList(Param(keyword) String keyword, Param(category) Integer category, Param(offset) int offset, Param(limit) int limit); int countNews(Param(keyword) String keyword, Param(category) Integer category); News selectById(Integer id); int increaseViews(Integer id); int insert(News news); int update(News news); int delete(Integer id); }对应的XML映射文件关键片段select idselectNewsList resultTypeNews SELECT * FROM t_news where if testkeyword ! null and keyword ! AND (title LIKE CONCAT(%, #{keyword}, %) OR content LIKE CONCAT(%, #{keyword}, %)) /if if testcategory ! null AND category #{category} /if AND status 1 /where ORDER BY is_top DESC, create_time DESC LIMIT #{offset}, #{limit} /select注意点where标签会自动去掉第一个多余的AND这个很实用。用CONCAT(%, #{keyword}, %)方式拼模糊查询不要直接写成%${keyword}%那样会有SQL注入风险。is_top DESC, create_time DESC能实现置顶资讯排在前面同一级别内时间新的在前这是实际项目常用的排序策略。浏览量增加采用独立SQLUPDATE t_news SET views views 1 WHERE id #{id}不要先查出来再加再更新那样既慢又容易出错。4.5 第五步院校和专业模块院校模块的核心是多条件筛选。在Service层组装查询条件public Result getUniversityList(String province, String type, String keyword, int page, int pageSize) { int offset (page - 1) * pageSize; ListUniversity list universityMapper.selectList(province, type, keyword, offset, pageSize); int total universityMapper.countList(province, type, keyword); MapString, Object data new HashMap(); data.put(list, list); data.put(total, total); data.put(page, page); data.put(pageSize, pageSize); return Result.success(data); }院校详情页除了显示院校信息还要显示该院校开设的专业列表和历年分数线。这里需要用到院校专业关联表select idselectMajorsByUniversityId resultTypemap SELECT m.id AS major_id, m.name AS major_name, um.score_line, um.exam_subjects FROM t_university_major um JOIN t_major m ON um.major_id m.id WHERE um.university_id #{universityId} /select这里用resultTypemap偷懒了更规范的做法是定义一个VO类。毕设中建议定义VO类因为论文里画类图更好看代码可读性也更强。4.6 第六步用户的收藏功能收藏功能很简单但有几个坑必须注意。收藏接口设计PostMapping(/api/favorite/add) public Result addFavorite(RequestParam Integer targetId, RequestParam Integer type, HttpSession session) { User loginUser (User) session.getAttribute(loginUser); if (loginUser null) { return Result.error(请先登录); } // 校验是否已经收藏过避免重复收藏 Favorite existing favoriteMapper.findByUserAndTarget(loginUser.getId(), targetId, type); if (existing ! null) { return Result.error(您已经收藏过了); } Favorite favorite new Favorite(); favorite.setUserId(loginUser.getId()); favorite.setTargetId(targetId); favorite.setType(type); favorite.setCreateTime(new Date()); favoriteMapper.insert(favorite); return Result.success(收藏成功); }取消收藏就是按user_id和target_id删除记录。收藏列表是一个联表查询根据type字段的不同关联不同的表select idselectFavoriteList resultTypemap SELECT f.id AS favorite_id, f.type, f.create_time AS favorite_time, CASE WHEN f.type 1 THEN n.title ELSE u.name END AS title, CASE WHEN f.type 1 THEN n.id ELSE u.id END AS target_id FROM t_favorite f LEFT JOIN t_news n ON f.type 1 AND f.target_id n.id LEFT JOIN t_university u ON f.type 2 AND f.target_id u.id WHERE f.user_id #{userId} ORDER BY f.create_time DESC /select这种CASE WHEN联表写法是一个比较实用的技巧但在数据量大时性能一般。毕设级别完全够用而且答辩时能解释清楚这样写的理由。4.7 第七步论坛模块发帖回帖论坛模块是展示事务和嵌套查询的好题材。发帖时校验用户登录状态写入t_post表状态默认0待审核。回帖时除了插入t_reply还要更新t_post表的reply_count加一这两个操作建议放到同一个事务里Transactional public Result reply(Integer postId, Integer userId, String content) { // 1. 插入回复 Reply reply new Reply(); reply.setPostId(postId); reply.setUserId(userId); reply.setContent(content); reply.setCreateTime(new Date()); replyMapper.insert(reply); // 2. 更新帖子的回复数 postMapper.increaseReplyCount(postId); return Result.success(回复成功); }Transactional加在Service方法上如果第二步抛出异常第一步的插入操作会自动回滚不会出现有回复但回复数没加的数据不一致问题。这个点很小但答辩时你说我用事务保证了数据一致性评委是会认可的。帖子列表页要显示作者昵称、回复数量、最后回复时间需要联表查询t_post和t_user再把聚合结果映射到一个VOpublic class PostVO { private Integer id; private String title; private String content; private String nickname; private Integer replyCount; private Date createTime; private Date lastReplyTime; // getter/setter }MyBatis映射中用LEFT JOIN把用户昵称带上来再用GROUP BY p.id保证每行帖子对应一条记录。4.8 第八步管理员后台的资讯发布后台资讯发布要支持图片上传。最简单的做法是上传到本地目录再通过映射访问静态资源。在配置类中注册资源映射Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 将/uploads/** 映射到本地磁盘目录 String uploadPath System.getProperty(user.dir) /upload/; registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadPath); } }上传文件用MultipartFilePostMapping(/api/admin/upload) public Result upload(RequestParam(file) MultipartFile file) { if (file.isEmpty()) { return Result.error(上传文件不能为空); } String originalFilename file.getOriginalFilename(); String ext originalFilename.substring(originalFilename.lastIndexOf(.)); String filename UUID.randomUUID().toString().replace(-, ) ext; String uploadDir System.getProperty(user.dir) /upload/; File dir new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } try { file.transferTo(new File(uploadDir filename)); return Result.success(/upload/ filename); } catch (IOException e) { e.printStackTrace(); return Result.error(上传失败); } }注意文件名用UUID重命名避免中文文件名和路径问题。同时要对文件扩展名做白名单校验只允许jpg、png、gif等常见图片格式防止有人上传可执行文件。5. 常见问题与排查技巧实录我校验过的坑一个个列给你做毕设最怕的不是不会而是遇到问题不知道怎么排查。下面这些坑是我带学生做这个项目时真实遇到过的按出现频率和杀伤力排序。5.1 数据库连接报错Communications link failure这个报错90%是数据库没启动或者数据库地址端口不对。排查思路先看MySQL服务有没有启动。Windows下按WinR输入services.msc找到MySQL服务启动它。再看application.yml里的url、username、password有没有写错。最常见的就是密码写错尤其是root密码设置了新密码但配置里还是默认的123456。最后看URL里是不是少了serverTimezone参数MySQL 8.x必须有这个参数否则会报serverTimezone异常或者连接超时。5.2 MyBatis的resultType映射不上字段全是null这个几乎每个新手都会遇到。数据库字段是create_time实体类是createTime如果没开启驼峰映射查询结果就是null。解决方案是确保application.yml里包含mybatis: configuration: map-underscore-to-camel-case: true如果你的mybatis是独立配置的不是在spring boot配置文件里那么在mybatis-config.xml里写settings setting namemapUnderscoreToCamelCase valuetrue/ /settings还有一种情况是实体类属性类型和数据库字段类型不匹配比如数据库中status是tinyint实体类是Integer这个不会报错但要注意取值范围。5.3 前端页面请求跨域如果你用前后端分离的方式开发前端8081端口后端8080端口请求时会报跨域错误。在Spring Boot中添加跨域配置Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOriginPattern(*); config.addAllowedMethod(*); config.addAllowedHeader(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }注意addAllowedOriginPattern不要用addAllowedOrigin(*)因为后者在allowCredentials为true时会被浏览器拒绝。5.4 拦截器放行路径没配好导致静态资源也被拦截这是我见过最多的问题。拦截器拦了/**结果CSS、JS、图片全被拦页面白板。正确做法是在注册拦截器时放行静态资源registry.addInterceptor(new LoginInterceptor()) .addPathPatterns(/**) .excludePathPatterns(/, /login, /register, /api/login, /api/register, /css/**, /js/**, /images/**, /upload/**, /api/news/**, /api/university/**);5.5 富文本编辑器内容保存后HTML标签丢了有些同学用wangEditor时前端把内容传成了纯文本后端接收后存进数据库再显示时变成一个纯文本段落。原因是wangEditor的txt.html()才会返回带标签的HTML而txt.text()只返回纯文本。前端获取内容时一定用html()方法。另外注意后台富文本编辑器和前端详情页都要做XSS过滤最简单的做法是配置一个过滤器把script标签转义掉。毕设不用做得太深但至少要能应对基础测试。5.6 请求参数乱码问题项目中出现中文乱码先检查数据库编码再检查前端页面编码最后检查请求响应编码。数据库层面表结构要设置为utf8mb4CREATE DATABASE kaoyan DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;如果你已经建好了库可以用ALTER DATABASE kaoyan CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;然后每张表也要改。Spring Boot层面在application.yml里配置characterEncodingspring: http: encoding: charset: UTF-8 enabled: true force: true从Servlet 4.0起Spring Boot 2.x中这个配置已经默认开启但你最好显式写出来给答辩老师看你的配置意识。5.7 部署或演示时8080端口被占用毕业答辩现场你的电脑上可能有其他程序占用了8080端口。可以用命令查看netstat -ano | findstr 8080找到PID后在任务管理器里结束进程或者直接改application.yml里server.port为8081等不冲突端口。我建议你在答辩前专门测试一次换端口后项目是否正常这个操作虽然简单但现场临时改配置容易出错。5.8 忘记密码功能怎么做很多同学项目里没做忘记密码但现场演示时总有人会问。最简单的方案是管理员重置密码后台管理员可以查看用户列表点击重置密码后系统生成一个随机密码更新到数据库并把新密码显示在页面上。这个功能实现只要十几行代码但能堵住评委的嘴。5.9 数据量太少列表页空荡荡毕设演示时如果列表页只有一两条数据视觉效果非常差。建议前期写一个数据填充脚本用程序批量生成几十条院校数据、几十条资讯数据让页面看起来有内容。数据格式要尽量真实比如院校名称用真的大学名称注意别涉及敏感信息用常见高校名称没问题专业名称用计算机科学与技术、软件工程、电子信息、会计学这类常见专业。这些填充数据你在答辩文档里写测试数据即可。6. 从毕设到答辩你怎么把会做变成会说代码写完只是个开始答辩展示才是决定分数的一环。我用我自己的经验给你几个建议。6.1 答辩前的演示脚本不要等到答辩现场才想我该演示什么提前准备一个5分钟左右的演示流程登录页面演示注册一个新用户然后登录。前台资讯列表演示按分类筛选、搜索关键词。院校库演示地区筛选类型筛选点进详情看专业和分数线。收藏收藏一个院校然后去我的收藏中查看。论坛发一个帖子用另一个账号回复演示帖子回复数变化。后台管理员登录审核帖子发布一条新资讯回到前台刷新看新资讯出现。这套流程覆盖了系统的主要功能逻辑完整时间控制在8-10分钟评委问题也能自然带出。6.2 高频答辩题提前想好答案做这个题目评委大概率会问这几个问题为什么选用Spring Boot而不是传统的SSHStrutsSpringHibernate答Spring Boot简化了配置和部署内嵌Tomcat项目可以直接Jar包运行。同时它的自动配置机制能减少大量样板代码让我把精力集中在业务逻辑上。加上Spring Boot是目前企业主流对后续扩展也更友好。数据库表之间是什么关系答用户和帖子是一对多帖子和回复是一对多院校和专业是多对多通过中间表关联用户和资讯/院校之间通过收藏表实现多对多。浏览量功能怎么实现的答前端在进入详情页时异步调用一个接口后端执行UPDATE语句将views字段加一不做乐观锁因为浏览量的并发要求不高允许极端情况下有偏差。但为了防止刷新页面就能无限增加浏览量如果团队有精力可以做基于Session或IP的去重毕设不做也不会扣分。密码是怎么加密的答用的是BCrypt加密算法每次加密生成的哈希值带随机盐即使两个用户密码相同存储的哈希串也不同。校验时调用BCryptPasswordEncoder的matches方法用户输入密码不直接与数据库里的密文匹配而是通过算法还原后比对。项目中有没有用到Redis答如果没用就说当前系统规模下用MySQL加缓存优化满足需求。Redis可以在后续版本中用来做热点资讯缓存和Session共享这是一个可扩展的方向。这句话体现了你的思考深度比硬说没用过好得多。6.3 论文写作的几个技巧论文中需要放核心代码不要贴大段重复代码选最关键的5-8个方法即可比如登录注册、资讯搜索、收藏逻辑、转发逻辑。每个代码块前后都要有文字说明解释这段代码解决的问题。ER图一定要规范实体名、属性名、关系线要对齐。数据库设计章节建议用表格的形式列出每张表的字段比大段文字清楚得多。6.4 还能往哪些方向扩展这个系统往下做有几个很容易扩展的点你可以作为论文里的未来展望写上数据采集模块从研招网等公开渠道定时抓取招生简章和调剂信息自动入库。智能推荐根据用户的浏览记录和收藏行为推荐相似院校或热门资讯。在线模拟考试整合公共课历年真题用户在线答题并自动判分。PDF资料下载支持上传考研资料附件下载量统计做成资料库。移动端适配用Vue重写前端或者直接用微信小程序作为前端展示层。这些方向不需要你现在就做但在论文里写上系统支持二次开发可扩展为智能推荐平台显得你的设计有前瞻性。7. 一个过来人的一点真心话做了这么多年的开发和带毕设指导我特别想说一句毕设不是考试它是你向外界证明我能独立完成一个有价值的完整系统的机会。代码可以抄思路可以借但你必须对每一个模块如数家珍。答辩现场评委更看重的是你对自己作品的理解程度而不是这个系统用了多少高深技术。我个人做毕设时最后悔的一件事就是前期把大量时间花在纠结要不要用Redis要不要上VueElement UI这些技术选型上结果选型拖了一周代码紧赶慢赶。后来我带学生第一句话永远是先跑通再优化最后再美观。你觉得很炫的技术最后没能跑通在答辩老师眼里反而减分。相反一个普普通通的系统你能清楚说明表结构为什么这么设计、事务为什么加在这里、搜索为什么用LIKE而不是全文索引分数一定不差。最后再说一个小技巧项目完成后给数据库准备一个干净的初始化脚本把所有建表语句和必填测试数据放在一个sql文件里。你答辩时如果换了电脑或者现场环境有问题两分钟内就能把数据库重建出来。这招我自从第一次答辩翻车之后就再也没忘记过希望你也记住。
返回列表