ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI辅助编程实战:学生成绩管理系统从零到上线全流程

AI辅助编程实战:学生成绩管理系统从零到上线全流程 最近总有人问我AI辅助编程到底是噱头还是真能落地干活。我手上的答案很简单拿一个真实项目走一遍就知道。这篇文章我就以“学生成绩管理系统”为例把AI怎么辅助我完成一个Web项目从零到能跑的全过程捋一遍——包括业务需求拆解、技术选型、数据库设计、提示词怎么写、代码怎么生成、联调怎么测、踩了哪些坑。如果你正好在做Web开发、准备毕设或者想体验一下AI助写代码的真实工作流这篇应该能让你少走不少弯路。1. 项目定位与核心需求拆解学生成绩管理系统到底在管什么1.1 一个成绩管理系统背后的真实业务场景很多第一次接触这个项目的人会想不就是记录学生成绩嘛Excel都能干为什么要做个Web系统但把场景放大就不一样了。假设一个系里有12个班、每年级6个班每个班40人每学期开8门课光一次期末考试就会产生3840条成绩记录。这还只是一个年级的。教务老师要在这些数据里查某个学生的历次成绩变化、出一份班级平均分对比、筛选不及格名单、给家长打印成绩单——用Excel做这些事重复劳动量大得吓人而且特别容易出错。所以学生成绩管理系统要解决的不是“能不能存成绩”的问题而是“怎么高效地管成绩、查成绩、用成绩”。我给它拆成了四个核心需求点学生信息和班级信息的管理要能快速增删改查和模糊搜索课程信息和成绩信息的关联存储一门课对应多个学生的成绩一个学生也有多门课成绩这是一对多的典型场景多维度的成绩统计包括个人总分、排名、平均分、及格率、分数段分布成绩单的导出与打印这是教务场景里最常被忽略但使用频率极高的功能。把这些需求想清楚之后再去看AI辅助开发就有了靶子。AI擅长的是代码生成和结构化实现但前提是你得先把业务逻辑想明白否则问出来的代码一定是四不像。1.2 AI在这个项目里能帮什么、不能帮什么我对AI辅助编程的态度一直比较务实它不是一个能替你思考的架构师而是一个响应速度极快、知识面极广的结对程序员。你负责把“做什么”和“怎么做”的框架定清楚它负责把“具体代码长什么样”快速输出出来。具体到学生成绩管理系统AI能帮的环节非常明确根据你给的数据库字段描述生成建表SQL和对应的实体类根据一个接口的入参和返回结构生成完整的Controller-Service-Mapper三层代码根据页面截图或功能描述生成Bootstrap或Vue风格的表格、表单、弹窗代码在你报错的时候快速定位异常原因并给出修复方案。但它不能替你做的也很明显它不知道你的教务流程里影响最终成绩的平时分和期末考占比各是多少不知道班级管理员的权限边界是什么也不知道你想要成绩单上显示哪些字段。这些业务规则必须由你在提示词里写清楚或者在对话过程中逐步补充修正。所以AI助写这个项目的正确打开方式是先自己做需求分析和表结构设计然后让AI去落地编码再通过人工审查和联调把代码质量控住。这个思路我后面会反复用到。2. 技术选型定盘AI辅助下如何快速锁定一套稳定方案2.1 技术栈选择的底层逻辑成熟优先于新颖在AI辅助开发的场景下技术栈选择有一个特别容易被忽略的原则必须选AI训练语料里出现频率最高的方案。你选一个小众冷门框架AI生成出来的代码大概率是幻觉连篇你选Spring Boot Vue这套国内Web开发最常见的组合AI输出的质量和稳定性就会高很多因为它见过的相关代码可能是百万级以上的。我当时定下来的技术栈是后端Java 17 Spring Boot 3.x MyBatis-Plus MySQL 8.0前端Vue 3 Vite Element Plus组件库成熟AI生成的表单和表格代码非常稳定中间件使用Maven管理依赖使用Lombok简化实体类代码使用Druid作为数据库连接池部署形态前后端分离后端打包成Jar包运行在8080端口前端通过Nginx或Vite代理转发请求为什么会选这套方案一方面是这套组合在国内Web项目中太常见AI训练语料充足生成出来的代码基本不需要大改另一方面是MyBatis-Plus帮我们把大量单表CRUD操作简化成了框架内置方法让AI生成的Service层代码不至于冗余。还有一点值得说我看到热搜词里有人提到Spring Boot集成WebSocket的yml配置这个如果做成成绩实时通知、考试开始提醒之类的功能是可以加的但对一个标准的学生成绩管理系统来说属于增量需求不是核心。我的建议是先跑通核心CRUD再加这类功能别在一开始就引入复杂度。2.2 数据库设计先定表结构再让AI写实体数据库是整个系统最不能依赖AI的部分。我见过不少人让AI“帮忙设计表结构”生成出来的表要么缺字段要么字段类型不合理。我的做法是先把表结构设计好再让AI根据表结构生成实体类和Mapper。学生成绩管理系统的核心表我设计了五张表名用途关键字段student学生信息表id, student_no学号, name, gender, phone, class_idclass_info班级表id, class_name, grade年级course课程表id, course_name, credit学分, teacherscore成绩表id, student_id, course_id, score, exam_type平时/期中/期末, exam_datesys_user系统用户表id, username, password, role角色以score表为例我故意把exam_type设计成字段而不是分成平时成绩表、期中成绩表、期末成绩表原因在于同一门课的成绩记录放到同一张表里统计平均分和加权计算时会简单非常多。这个表设计细节直接决定了后面AI生成的SQL查询语句写起来顺不顺。表结构确定后我会把建表DDL直接丢给AI让它生成对应的实体类和Mapper接口。比如CREATE TABLE student ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键ID, student_no varchar(20) NOT NULL COMMENT 学号, name varchar(50) NOT NULL COMMENT 姓名, gender tinyint DEFAULT NULL COMMENT 性别1男 2女, phone varchar(20) DEFAULT NULL COMMENT 联系电话, class_id bigint DEFAULT NULL COMMENT 班级ID, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_student_no (student_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT学生信息表;这个DDL一旦给到AI它生成的实体类基本就是照着字段映射不会有错。3. AI助写的实操流程从提示词到可运行代码的完整链路3.1 高质量AI编程提示词的设计方法很多人用AI写代码效果差问题真不在AI而在提示词写得太随意。比如有人直接问“给我写一个学生成绩管理系统”这种问题AI只能给你一个飘在天上的大纲根本落不了地。我总结出一套适合Web项目开发的提示词结构叫“角色任务输入约束输出格式”五件套。举个例子我要生成后端成绩列表查询的Controller提示词是这样写的你是一名有10年经验的Java高级工程师擅长Spring Boot开发。 现在需要为学生成绩管理系统编写一个成绩管理模块。 已有实体类 Score包含字段id、studentId、courseId、score、examType、examDate。 请编写Controller层代码实现以下功能 1. 分页查询成绩列表支持按学生姓名、课程名称、考试类型筛选 2. 新增成绩记录 3. 修改成绩记录 4. 删除成绩记录。 要求基于MyBatis-Plus实现使用统一的返回结果类Result包含code、message、data三个字段。 请直接输出完整代码并附上关键注释。注意这里我给了角色设定给了明确的任务边界给了已有的实体类信息给了技术约束还指定了返回结果格式。AI拿到这种提示词之后生成的Controller基本是可用的不会出现“自己发明实体字段”的情况。3.2 后端代码生成分层生成的效率远高于一次生成我实测下来AI一次生成整个项目的代码风险高、改动成本也大远远不如按层生成来得靠谱。我习惯按这条路走一遍先让AI生成Controller层代码确认接口路径和参数设计没问题再让它生成Service接口和实现类。Service是业务逻辑的核心需要把复杂查询的SQL逻辑在这里定义清楚。最后生成Mapper层代码这部分如果用了MyBatis-Plus几乎不需要写SQL基础的增删改查都内置了。真正的复杂查询比如按班级统计平均分、按课程统计各分数段人数才需要自己写SQL或让AI帮忙生成。这里我想特别说一个经验给AI报需求的时候一定要带上表结构的字段名。因为AI不认识你的数据库只能根据你提供的字段名来拼SQL。聪明一点的AI会编字段但字段名跟数据库对不上代码跑起来就是一片红。所以宁可每次提示词里多复制几行字段说明也不要让AI自由发挥。3.3 前端页面生成从首页到详情的渐进式迭代后端做得差不多了再让AI生成前端页面。学生成绩管理系统的前端页面主要包括登录页、首页Dashboard、学生管理页、课程管理页、成绩管理页、成绩统计页。我通常会先让AI生成一个基于Element Plus的“成绩管理页”包含一个表格、一个搜索表单、一个新增/编辑对话框然后截图或描述让AI继续调整样式。AI生成前端代码有个小技巧把接口的数据结构先给AI看。比如你告诉它成绩列表接口返回的数据是[{id: 1, studentName: 张三, courseName: 高数, score: 89, examType: 期末}]AI生成的el-table列就能直接绑对字段省掉大量的调试时间。至于风格我让AI统一使用Element Plus的Table、Form、Dialog、Message组件这组组件在AI训练语料里的代码足够多生成出来的交互效果相对统一。一个能跑的界面比一个花哨但README写得天花乱坠的界面有用得多。4. 核心功能模块实现详解从CRUD到统计报表4.1 成绩管理模块背后的数据关联是核心成绩管理这个模块表面看就是一个成绩表的增删改查但实际写起来门槛在数据关联。你要在成绩列表里显示的是“张三 93分 高数”而不是“studentId1 courseId3 score93”这种开发人员才看得懂的原始数据。这就需要在Mapper层做关联查询。用MyBatis-Plus的话可以配合自定义SQL实现select idselectScorePage resultTypecom.example.vo.ScoreVO SELECT s.id, st.student_no AS studentNo, st.name AS studentName, c.course_name AS courseName, s.score, s.exam_type AS examType, s.exam_date AS examDate FROM score s LEFT JOIN student st ON s.student_id st.id LEFT JOIN course c ON s.course_id c.id where if teststudentName ! null and studentName ! AND st.name LIKE CONCAT(%, #{studentName}, %) /if if testcourseName ! null and courseName ! AND c.course_name LIKE CONCAT(%, #{courseName}, %) /if if testexamType ! null and examType ! AND s.exam_type #{examType} /if /where ORDER BY s.create_time DESC /select这种带LEFT JOIN和动态查询条件的SQL让AI生成时最容易出的问题是where标签写错位置或漏了if里的条件判断。所以我是先搭好SQL骨架再让AI帮我把重复度高、模式固定的部分填上。4.2 统计报表模块一个JOIN加GROUP BY就能搞定的重头戏成绩统计是这系统里最有价值的部分因为教务老师真正看重的不是一条条的成绩记录而是汇总之后的信息这个班这次期末平均分多少哪门课挂了最多人全年级前20名是哪些学生。用SQL表达的话班级平均分统计可以这样写SELECT c.class_name AS className, ROUND(AVG(sc.score), 2) AS avgScore, COUNT(sc.id) AS examCount, SUM(CASE WHEN sc.score 60 THEN 1 ELSE 0 END) AS failCount FROM score sc LEFT JOIN student st ON sc.student_id st.id LEFT JOIN class_info c ON st.class_id c.id WHERE sc.exam_type 期末 GROUP BY c.id ORDER BY avgScore DESC这个查询在AI辅助下的生成速度非常快但我强调过一件事AVG函数、SUM函数配合CASE WHEN的条件计数一定要先确认数据库字段类型。如果score字段不小心被设计成了varchar那么AVG出来的结果会让你怀疑人生。所以建表时成绩字段必须是DECIMAL(5,2)或INT型这个属于数据规范和表结构设计的问题AI帮不了你。统计报表的后端接口返回给前端后前端需要把它渲染成图表。这一步我让AI生成一个基于ECharts的柱状图组件大概逻辑就是接受后端返回的班级名称数组和平均分数组然后渲染成图表。实测下来ECharts的option配置在AI眼里简直是训练集里面的老熟人生成出来的代码基本不用改。4.3 页面PDF打印成绩单怎么实现Web端直出PDF热搜词里有人搜“web页面pdf打印”这正好是成绩管理系统中一个实用的场景给每个学生打印成绩单。实现思路通常有三种前端用浏览器自带的window.print()打印指定区域好处是零依赖坏处是样式控制能力弱前端引入html2canvas把页面区域转成图片后再打印或导出实现简单但清晰度一般后端用iText或POI生成PDF文件前端直接下载样式可控性最强但开发量稍大。对于学生成绩管理系统我认为最务实的方案是第一种配合一点样式微调。把要打印的区域包在一个div中打印时把其他区域隐藏function printScoreSheet() { const printContent document.getElementById(print-area); const originalTitle document.body.innerHTML; document.body.innerHTML printContent.innerHTML; window.print(); document.body.innerHTML originalTitle; window.location.reload(); }AI生成这种经典JS函数几乎是秒出但要提醒你的是DOM操作重置之后Vue的响应式数据可能丢失所以这个函数适合用在纯展示页面上比如成绩单预览页。如果表单页面也这样做保存后再恢复页面就需要window.location.reload()兜底。这个坑我是踩过的特意把reload写进代码里就是为了避免页面状态错乱。5. 实操过程记录IDEA 2024环境下从零搭建整个项目5.1 Spring Boot项目初始化与关键依赖配置我用的是IDEA 2024版本新建项目时可以直接选择Spring Initializr然后勾选Web、MySQL Driver、Lombok等依赖。这一步有一个容易被AI辅助搞混的地方AI生成代码时会默认你有一整套pom.xml但新项目的依赖是你自己勾的所以提示词里最好带上你现有的依赖列表让AI在这套基础上补充。核心的pom.xml依赖长这样dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.5/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.20/version /dependency如果你的项目里tomcat和数据库驱动版本不对启动时报“Failed to load plugin”之类的问题很常见。实际上这种报错大多是版本冲突不要盯着一长串报错信息发愁先检查pom里有没有引入两个冲突的依赖。5.2 application.yml配置与MyBatis-Plus集成配置文件是项目能跑起来的地基我通常会这样写server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/grade_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: root type: com.alibaba.druid.pool.DruidDataSource mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml configuration: map-underscore-to-camel-case: true logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0有几个细节值得展开说。url里的serverTimezoneAsia/Shanghai是必须的否则会报时区异常map-underscore-to-camel-case要开启否则数据库字段student_no映射不到实体的studentNo属性上。如果你用了逻辑删除记得配好logic-delete相关参数AI生成的查询语句会自动带上deleted过滤条件。5.3 前端工程创建与Vue页面跑通前端我用Vite来创建Vue3项目命令很简单npm create vuelatest npm install element-plus npm install axios npm install echarts然后配置axios请求代理把前端的/api请求转发到后端8080端口。这个配置在vite.config.js里写server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } }前端页面写完之后的联调阶段有一个高频问题前后端联调时接口返回403或404。403大概率是跨域没配好那就需要在后端加一个CorsConfig或者在Controller上加CrossOrigin注解。404则是代理路径和Controller的RequestMapping对不上。我习惯在前端请求时统一加/api前缀后端Controller的RequestMapping里就别再写/api了避免重复。5.4 联调测试的完整流程记录联调阶段我通常按这个顺序走先测登录再测学生管理最后测成绩和统计。登录测试通过说明数据库连接和用户表没问题学生管理通了说明基础CRUD链路没问题性能和复杂的统计放在最后。每测一个接口我会先用Postman把后端接口调通然后在前端页面上操作一遍。这个习惯帮我节省了大量排查前端还是后端问题的时间。一个真实的测试场景是这样的我让AI生成了成绩列表的分页查询接口结果前端一直拿不到第二页的数据。后来发现AI生成的SQL里LIMIT参数的顺序写反了LIMIT 1, 10和LIMIT 10, 1在语义上完全不一样。我直接在Postman里测试后端接口就快速锁定了问题不在前端而在后端SQL。所以我说AI能生成代码但联调这个环节还是得自己动手跑一遍因为你比AI更清楚业务上的正确行为是什么。6. 踩坑实录AI生成代码的典型问题与排查技巧6.1 常见问题速查表我在这套学生成绩管理系统实际开发过程中遇到的最典型的问题整理成了一张某种意义上可以直接抄作业的速查表问题现象根本原因解决方案接口返回500线上日志提示Unknown columnAI生成的查询条件里有数据库不存在的字段核对实体类字段和表字段映射关系前端表单提交报400 Bad RequestJSON字段名与后端实体属性名对不上在实体类上加JsonProperty或改前端字段名MyBatis-Plus分页不生效始终返回全量数据缺少分页插件配置新建MybatisPlusInterceptor并添加PaginationInnerInterceptor日期格式化后前端显示时间戳后端没做Jackson日期格式配置yml中配置spring.jackson.date-format页面PDF打印时内容和背景丢失打印样式未加载在media print中单独设置背景色和裁剪区域ECharts图表不显示容器div没有高度给图表容器设置固定或百分比高度这里我想特别说一下分页插件的问题。MyBatis-Plus自带的CRUD方法支持分页但必须在配置类里显式注册分页拦截器否则Page对象查出来的永远是全量数据。AI生成这类配置类经常漏因为它的上下文里没有你项目的包结构。所以拿到AI生成的代码第一件事就是检查有没有配置类被漏掉了。6.2 提示词迭代修正的核心经验AI写代码很少一次成功但很多人不知道如何有效修正AI的输出。我的做法是把错误日志或者前端报错信息原封不动粘给AI再补充说明期望的正确行为是什么。不要只说“你这个代码写错了”更好的说法是“当前返回结果出现了null字段期望返回成绩对应的学生姓名请检查LEFT JOIN条件中student表的关联字段”。还有一种情况AI生成了两套实现方式比如把删除设计为物理删除而你的需求是逻辑删除。这时需要在提示词里明确描述“系统要求数据不可物理删除使用MyBatis-Plus逻辑删除”让AI基于这个约束重新生成。提示词的修正过程本身就是在锻炼你对自己的业务逻辑的表达能力这是AI辅助开发中很有价值的副产品。6.3 如何判断AI生成的代码可不可用最后分享一个筛选AI生成代码是否值得使用的判据。拿到一段代码后我会先看三处第一实体类和数据库字段是否一一对应第二事务注解有没有加对位置——一般写在ServiceImpl类上而不是Controller上第三异常处理是不是被吞掉了——最好不要catch之后什么都不做至少要打日志。这三处过关了这个代码大概率能跑。如果这三处都不过关那还不如自己手写。AI助写的意义是把80分的代码快速产出后续的20分属于人工打磨。7. 一点个人体会如果你要问我这个项目做完之后最大的感受那就是AI助写代码这件事重心从来不在AI而在“你怎么定义需求、怎么拆解任务、怎么验证结果”。学生成绩管理系统本身不复杂但它把AI辅助开发的全流程完完整整走了一遍——从SQL到后端接口再到前端页面每个环节AI都参与了每个环节的产物我都做了审查和调整。我建议你动手做类似项目时不要直接甩给AI一句“帮我写一个成绩管理系统”就坐等结果。先花半小时画一画业务流程写清楚要几张表想明白哪些功能是必须的然后再打开AI对话窗口。把问题想得越清楚AI给你回报的效率就越高。另外一个特别想提醒的点是AI生成的代码一定要自己跑测试尤其是涉及金额、分数、日期这类精度敏感的数据。成绩管理系统的score字段哪怕精度错了0.5分在统计报表里都会被放大。顺手写一个基础的单元测试或者用手工数据验证一遍比什么都可靠。这个项目后续要扩展的话可以加WebSocket主动推送成绩发布通知也可以接一个简单的权限系统区分管理员和教师角色基础做好了之后这些都不会太难。
返回列表