1. 为什么我把课设从“做完交差”变成了“一套可复用提示词”
先说点实在的。很多人的课程设计是这么做的:拿到题目,上网搜一圈,找个差不多的源码改改,数据库结构照搬,页面换换颜色,写完报告交上去,任务完成。这套流程我大一的时候也走过,说实话,能学到的东西非常有限,而且做得特别心虚——答辩的时候老师随便问一个“你为什么这样设计表结构”就卡壳了。
做“蓝动记”这个项目的时候,我逼自己换了种思路。当时手头的事情比较多,除了这门课的课设,还在帮导师做个小系统,同时准备着实习面试。时间紧张,代码要是从零手写,一个月都未必能写完;可要是纯抄,又过不了自己心里那关。后来琢磨出一个办法:把自己的需求想清楚,拆细,写成一整套条理化的开发提示词,再基于这套提示词去生成前后端代码、数据库脚本和接口文档。我只需要做审核、修改、适配这三件事,效率一下子提了好几倍。
结果是,这套进销存系统我只用了两个星期就完成了主体功能,连课设报告里的架构图、流程图、表结构说明都是顺着提示词的输出整理出来的。更关键的是,我手里攒下了一个通用性很强的提示词模板,之后接其他项目,改改业务描述、调调字段定义,就能直接复用。
说白了,这事的价值不在于“用AI写出了课设”,而在于把“你心里清楚要做什么”这个模糊状态,转化成“机器也能理解并执行的精准需求描述”。这种能力,工作中比敲几千行代码值钱得多。
这篇文章就把完整思路、提示词模板、踩过的坑和实际效果全部展开,从项目拆解到技术选型再到复用方法,一次性说清楚。
2. MVP版的进销存,到底该切哪些功能进来
进销存在UML图里能画出一大堆:采购管理、销售管理、库存管理、应收应付、报表统计、权限管理、多仓库、批次序列号、生产组装……真全做出来,那不是课设,是ERP。MVP的原则是:把核心业务跑通,砍掉一切“没有也能活”的部分。
“蓝动记”这个名字很简单,定位就是一个中小型贸易商行的进销存工具,所以第一期MVP我划定了几条硬边界:
- 只做单仓库,不做多仓调拨和多级库存
- 商品不做批次和序列号管理,只按SKU计库存数量
- 不做复杂财务模块,应收应付先砍掉,只记录进价和售价
- 不做审批流,入库单审核直接用“确认入库”这个动作实现
- 权限只区分管理员和普通操作员,不再细化到按钮级别
这样切完之后,核心模块就非常清晰了。
2.1 明确的角色划分与页面路径
系统里只有两种角色。管理员能看全部菜单,包括商品管理、入库管理、出库管理、库存查询、供应商管理,以及操作员账号的开设;普通操作员只负责日常录单、出库和查库存,不碰基础数据的增删改。
页面路径也按操作习惯来设计,不是照搬教科书上的模块树。登录之后先进“工作台”,工作台上有三块:今日入库笔数、今日出库笔数、低库存商品预警(这个对于MVP来说体验提升非常明显)。左侧菜单有条理地排开,核心操作不需要超过三跳。
2.2 数据模型的边界怎么定
数据库是进销存的命根子。表结构设计得好不好,直接决定后续加功能的时候是轻松扩展还是推翻重来。MVP阶段我设计了这几张核心表:
| 表名 | 作用 | 关键字段 |
|---|---|---|
| users | 用户表 | id, username, password, role, created_at |
| suppliers | 供应商表 | id, name, contact, phone, address |
| products | 商品表 | id, sku, name, category, spec, unit, price_in, price_out, stock, min_stock |
| stock_in | 入库单表 | id, supplier_id, operator_id, total_amount, status, in_date, remark |
| stock_in_item | 入库单明细表 | id, stock_in_id, product_id, quantity, price, amount |
| stock_out | 出库单表 | id, customer_id, operator_id, total_amount, status, out_date, remark |
| stock_out_item | 出库单明细表 | id, stock_out_id, product_id, quantity, price, amount |
注意一个细节:库存没有单独建表,而是直接冗余在products表的stock字段里。这在严格的ERP设计里“不标准”,因为缺乏流水可追溯,但MVP阶段这样做完全合理——每次出入库操作都在事务里同步更新stock字段,库存查询就变得极快,连join都不用。
如果要追溯历史,也有办法,后续加一张stock_log流水表就能解决。这就是MVP的取舍:先保证核心流程跑顺,再把审计跟踪补上。
2.3 入库出库的核心业务流程
入库的流程是:操作员先创建入库单,选择供应商,然后一行行添加商品明细(商品下拉选择,自动带出当前进价,数量手动填),确认无误后点“确认入库”。此时做两件事:写入入库单主表和明细表,同时把商品的stock字段加上对应数量。这张单子从此变成历史记录,不能再改。
出库的流程对称:创建出库单,选客户(MVP里客户可以用一个简单的customer字段存文本,但为了规范我建了一张customers表,后面标题里有需要再加,先预留),添加商品明细时系统自动显示当前库存,如果填写数量大于库存,直接在前端拦截并提示“库存不足,当前可用库存为XX”,确认出库后扣减库存。
这样一套流程走下来,最简单的进销存闭环就已经成立了:进货多了库存,卖货少了库存,每一笔出入库都有单据可查。
3. 技术选型:JSP+Servlet被吐槽了这么多年,为什么我还用它
说到技术选型,这是我在开发之前就认真纠结过的。一开始考虑过Spring Boot + Vue前后端分离,也考虑过Spring Boot + Thymeleaf,甚至连照着B站教程做一套若依脚手架改改的念头都有过。但最后压下来,选了JSP + Servlet + MySQL这套“老古董”。
做这个选择有三层考虑,下面详细说清楚,就不只是“课设要用”这么一个理由了。
3.1 教学验收的角度:能说清楚的才是自己的
课设答辩和真实项目最大的不同在于,老师会追问你实现细节。用Spring Boot + Vue,项目结构一大半是框架帮你拉好的,依赖包几百个,你连每个注解的原理都讲不全,答辩的时候特别容易被问穿。
JSP + Servlet就非常直白。Servlet处理请求、设置参数、转发页面,JSP负责把数据渲染成HTML,请求从浏览器发出到Tomcat再到Servlet再到JSP再响应的完整链路,每一环都能讲清楚。Filter做登录拦截和编码处理,Listener在启动时初始化数据源,JDBC从DriverManager到PreparedStatement到ResultSet,这条路子对于课设而言是“能亲手讲明白每一行代码在干什么”的路线。
这不是说框架不好。工作里我完全支持直接用Spring Boot,但课设的场景很特殊——它更考察你对Web基础原理的理解,而不是对框架生态的熟悉程度。
3.2 资源约束下的实际可操作性
JSP + Servlet技术栈非常轻。一台普通笔记本,JDK + Tomcat + MySQL + IDEA,四样东西装好就能跑,不依赖Maven复杂依赖解析,不依赖Node环境,不用考虑跨域、打包和部署问题。直接把Web项目放进Tomcat的webapps目录,启动Tomcat,浏览器打开localhost:8080,完事。
这对小组协作也很友好,导出war包就部署完成。有些同学的电脑配置一般,开一个IDEA再开一个Android Studio已经卡得不行了,再让他跑前端工程、后端工程、Node服务几个进程,分分钟崩溃。
3.3 性能面其实够用
“JSP慢”“Servlet老”这些话说了很多年,但得看场景。一个课程设计级别的进销存,最多几十个并发用户,JSP的预编译、Servlet的单实例多线程模型、JDBC连接池复用,这套组合足够应付。
在实际测试中,我用JMeter模拟了50个并发用户同时查询库存列表,平均响应时间在120ms左右,完全在可接受范围内。真正会拖慢JSP项目的,往往是没做连接池、频繁创建数据库连接、或者SQL写得稀烂。这几个坑避开了,性能根本不是问题。
3.4 如果换成现代技术栈,提示词该怎么改
松绑说一句,提示词这套方法论同样适用于Spring Boot + Vue组合。如果是Spring Boot + Vue前后端分离的项目,提示词里的“修改index.jsp”就得改成“修改前端router对应的Vue组件,调用后端的/api/inventory接口”。但核心提示词不变:角色定义、项目概述、技术栈、表结构JSON、模块功能描述、接口参数约定。这套骨架在哪个技术栈里都能复用,只是描述侧重点不同。
4. 整套项目提示词,从零到一手把手搭出来
既然核心是“可复用开发提示词”,那这套提示词本身才是这篇文章最大的交付物。一步步说明它的写法、内容和用法。
我习惯把提示词分两层:顶层是项目主提示词,一次对话开始时喂给AI,用来锁定整个项目的方向和约束;第二层是功能点提示词,每开发一个模块时单独发起,聚焦在单个功能上。这样能避免主线被细节带偏,也方便增量开发。
4.1 项目主提示词模板(可直接复制的第一版)
你是一名经验丰富的Java Web全栈工程师,专注于JSP + Servlet + MySQL技术栈的项目开发。 现在需要开发一套进销存管理系统(MVP版本),系统名称“蓝动记”。
项目背景:某小型贸易商行需要一套内部使用的进销存管理系统,用于管理商品信息、供应商信息、采购入库、销售出库以及实时库存查询。
硬性约束如下:
- 技术栈固定为:JSP + Servlet + MySQL 8.0,部署在Tomcat 9上。
- 不使用任何第三方框架,不引入Maven,所有jar包手动导入到WEB-INF/lib目录,包括mysql-connector-java、gson等。
- 用户角色分为管理员和普通操作员,管理员拥有全部功能权限,操作员只能进行出入库操作和库存查询。
- 数据库使用UTF-8编码,数据库名为landongji。
- 页面风格要求简洁清晰,使用纯HTML + CSS实现,不引入Bootstrap等前端框架(或者引入,根据项目需要说明原因)。
- 请求路径统一以.do结尾,如 /login.do, /product/list.do, /stock/in.do。
- 所有对数据库的操作必须使用PreparedStatement,严禁字符串拼接SQL。
- 每个Servlet建议采用继承HttpServlet并重写doGet和doPost的方式,action类型通过隐藏字段或路径区分。
- 项目完成后提供:数据库建表SQL脚本、Web目录结构、部署说明。
这个主提示词的信息密度决定了AI输出质量的40%。技术栈约束一定要写死,角色权限要写清楚,路径风格要统一,这样才能保证AI生成的不同模块之间不会出现“各自为政”的问题。
4.2 表结构提示词的写法细节
表结构是进销存系统的关键,AI理解业务的关键信息来源。不能只说“帮我建几张表”,要让AI理解业务语义和完整字段。我实际的提示词是这样组织的:
基于以下业务规则设计MySQL 8.0建表SQL,要求所有表使用InnoDB引擎,编码utf8mb4。
- 用户表:id(主键自增)、用户名(唯一)、密码(MD5加密存储)、角色(admin/operator)、创建时间。
- 供应商表:id、供应商名称、联系人、联系电话、地址、备注。
- 商品表:id、SKU编码(唯一)、商品名称、分类、规格、单位、进货价、销售价、当前库存数量、最低库存预警值、创建时间。
- 入库单主表:id、入库单号(格式RK+年月日+四位序号)、供应商id、操作员id、总金额、入库时间、备注。
- 入库单明细表:id、入库单主表id、商品id、进货数量、进货单价、行金额。
- 出库单主表:id、出库单号(格式CK+年月日+四位序号)、客户名称、操作员id、总金额、出库时间、备注。
- 出库单明细表:id、出库单主表id、商品id、销售数量、销售单价、行金额。
额外要求:在商品表的插入语句中预置至少10种常见商品数据,供应商预置5条数据,方便测试。
这里把入库单号、出库单号的生成规则写清楚非常重要,AI生成的代码里面就能直接实现单号生成器逻辑,不用后补。
4.3 功能模块提示词的分工写法
进销存功能模块比较多,最合理的做法是一个模块一个提示词,每个模块的提示词都遵循统一的格式。下面拿“入库功能”作为示例:
【功能模块】采购入库 【业务描述】操作员登录系统后,点击“入库管理”,进入入库单列表页,点击“新增入库单”,选择供应商,填写入库备注,然后添加多条商品明细(每行包括商品选择、数量、进货单价),前端实时计算行金额和总金额。点击“确认入库”后,系统完成二件事:一是将入库单主表和明细数据写入数据库;二是在同一个事务中,更新对应商品的库存数量(库存 = 库存 + 入库数量)。 【约束条件】
- 未登录用户访问该页面时,跳转到登录页。
- 操作员的ID从当前登录Session中获取,不允许前端传入。
- 商品下拉框的数据来自商品表中所有商品,展示格式为“SKU - 商品名(当前库存)”。
- 入库单号在Controller层使用日期格式加当天序号生成,序号从数据库查最大单号的后四位加一。
- 提交到Servlet的参数,无论是主表字段还是明细字段,均以JSON格式提交,由后端解析。
- 所有入库操作需要事务控制,任一步失败则整体回滚。 【涉及页面】
- stock_in_list.jsp:入库单列表
- stock_in_add.jsp:新增入库单页面
- StockInListServlet, StockInAddServlet, StockInSaveServlet
信息量越大,生成的代码越精确,尤其是约束条件这条,直接决定AI生成的后端代码能不能和你前面的模块接上。
4.4 提示词里的“提交与验收清单”
这是我在第二版提示词里加上的,也是最有用的改进之一。在完成了所有模块的开发提示词之后,追加一段:
全部功能开发完成后,请执行以下自检清单:
- 检查是否所有的Servlet路径都以.do结尾,并且和JSP页面中的form action和超链接一致。
- 检查数据库连接是否有泄漏风险,每一个PreparedStatement、ResultSet、Connection是否在finally块或try-with-resources中关闭。
- 检查登录Filter是否对除login.do、静态CSS/JS以外的请求都做了拦截。
- 检查入库和出库操作是否都开启了事务。
- 检查库存不足时系统是否有提示。
- 检查页面上的按钮,录入员不应看到用户管理按钮。
有了这个“验收清单”,AI生成完代码后会自动做一轮自查,很多小bug在萌芽期就被消灭了。这一步帮我节省了大量的联调时间。
5. 跑通后的真实效果和优化经验
5.1 基线版本的实测结果
我的基线版本基于这套提示词生成后,做了一些人工调整,最终的运行效果如下:
- 项目结构:Java源码约12个Servlet、5个工具类、8个JSP页面、JDBC工具类1个
- 功能完整度:登录权限、商品CRUD、供应商CRUD、入库操作、出库操作、库存查询、低库存预警、出入库历史记录,全部跑通
- 数据库:8张表,预置测试数据20条
- 部署耗时:从零到浏览器能访问,约10分钟
在Tomcat 9 + MySQL 8.0的环境下,实测没有任何404或500错误,基本达到当天拿给老师看demo也不慌的程度。
5.2 优化一:密码加密不能直接用MD5
提示词里最初写的是“密码MD5加密存储”,后来仔细想了下,MD5毕竟不安全,作为一个在博客里分享的方案,不能误导别人。所以在第二版我改成了加盐的SHA-256。具体做法是每个用户有一个随机盐值,存入数据库时拼接后的字符进行哈希。同样是十几行代码的事,安全系数天差地别。建议你自己做的时候也这样写,就算课设也一样,好习惯从早期养成。
5.3 优化二:商品下拉框的可用性体验
最初生成的下拉框直接把所有商品的SKU和名称拼成一个超长的option列表,当你拥有上百个商品时,这个下拉框就崩溃了——一是长到找不到想要的那一项,二是一次性渲染几百个DOM节点会让页面卡顿。
我在修改的时候给商品选择框加了一个搜索过滤功能:输入关键字时通过AJAX请求过滤后端接口,只返回匹配的商品。这个小改进让录入效率提升了一大截,实际操作体验直线上升。
5.4 优化三:数据库连接池替换
提示词的第一步生成的是“JDBC工具类直接使用DriverManager.getConnection”。这在MVP阶段能用,但是每次请求都要创建和销毁连接,数据库压力比较大,我也提到过这个问题。后来我把JDBC工具类替换成了Alibaba Druid连接池:pom里换成druid的jar,写一个DruidUtil工具类读取配置文件,然后在Servlet里把原来通过JDBCUtil.getConnection()的调用换成DruidUtil.getConnection()。
具体的改法很简单,给一个参考的Java代码:
public class DruidUtil { private static DataSource dataSource; static { try (InputStream in = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties")) { Properties props = new Properties(); props.load(in); dataSource = DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }对应的druid.properties文件:
driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/landongji?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username=root password=你的密码 initialSize=5 maxActive=20 minIdle=5 maxWait=5000替换之后,高并发下数据库连接稳定性大幅提升,同时因为连接池本身是Druid,还能直接在页面上访问/druid/index.html查看SQL监控和慢查询记录,联调和定位问题都方便得多。
5.5 踩过的坑:提示词生成了代码,但事务控制缺失
第一次按提示词生成的“入库保存”功能,让我印象极深。它会先插入主表,再插入明细表,最后更新商品库存。前两步被一个Connection对象包在了一个事务里,看似没什么问题,但到了“第三步更新库存”——那个Connection居然重新调用了一次getConnection(),跟前面的事务完全不是一个连接,库存更新的失败不会导致前面两张表的数据回滚。
排查了很久才定位到这个问题,后来我在提示词的“功能模块约束条件”里明确加了一条:
整个功能中,从创建连接、开启事务到最终提交或回滚,所有数据库操作必须使用同一个Connection对象。事务范围内禁止重新获取连接。
加了这个限制之后,AI生成的代码里事务控制就老实多了。这个教训也让我意识到,提示词的本质不是“越模糊越有创意”,而是“越精确越可靠”。
6. 提示词复用:把“蓝动记”模板改成其他系统的完整过程
说了这么多,这篇文章的主标题里有个词很关键:“可复用”。所以这部分专门讲一下,当你已经拥有“蓝动记”的这套提示词之后,下个项目怎么快速改出来。
比如你现在要做一个“图书馆管理系统”,需求是:图书管理、读者管理、借书、还书、逾期查询。这个大方向,套用同一套提示词,只需要做四个步骤的替换。
6.1 第一步:替换项目概述和技术栈描述
把主提示词里的“小型贸易商行需要一套内部使用的进销存管理系统”替换成“高校图书馆需要一套图书借阅管理系统”。技术栈不需要变,还是JSP+Servlet+MySQL。
6.2 第二步:替换表结构提示词
把“供应商”换成“出版社”,把“商品”换成“图书”,把“入库单”换成“采购入库/新书入库”,把“出库单”换成“借书单/还书单”。核心的关联逻辑不变:图书表(对应商品表)、出版社表(对应供应商表)、借书单表(对应出库单一类)。
属性需要增加的,在表结构提示词里补上即可,比如图书的ISBN、作者、馆藏位置,这些字段直接写进JSON或建表SQL里。
6.3 第三步:替换功能模块描述
把“入库管理”的描述改成“新书到馆后批量入库,选择出版社,录入书名、ISBN、价格、数量,确认入库后馆藏数量对应增加”;把“出库管理”改成“读者借书登记,输入读者证号,选择要借的图书,点击确认后对应图书的馆藏数量减一”。约束条件、路径规则、事务规则、权限管理都不动。
6.4 第四步:替换验收清单的相关描述
把“检查库存不足时系统是否有提示”改成“检查馆藏数量为0时借书操作是否有明确提示”;把“检查入库和出库操作是否都开启了事务”改成“检查借书和还书操作是否都开启了事务”。
整个替换过程,熟练的情况下不超过两小时,换完就能拥有一个结构清晰、代码风格统一的新系统。这就是“可复用开发提示词”的杠杆价值。第一次做“蓝动记”可能花了两个星期,第二次做“图书馆管理系统”可能只需要两三天,这个效率提升是肉眼可见的。
7. 一些关于学习和开发的私人建议
曾经有一个学弟问我:“用提示词做课设,是不是有点不劳而获?”我当时回答他:如果直接拿着AI生成的代码交上去,那确实是不劳而获;但如果你把它当成一个“高水平的结对编程伙伴”,自己拿着需求文档逐条拆解,验证每段代码是否真的满足需求,自己调试、自己改bug,这就是正经的工程方法。
用这套提示词开发的整个过程里,我做的最多的事其实不是让AI写代码,而是让它解释为什么这么写、能不能换个写法、这个边界有没有处理。AI的回答能补充我的盲区,但决策权始终在我手上。这才是“AI辅助开发”的正确姿势。
如果你准备复刻这套做法,我给几个实操建议:
提示词不是一次成型的。写第一版的时候,你可能根本不知道要写什么约束;没关系,先写个大概,让AI生成第一版,跑起来看问题,然后反哺回提示词。我的那一版约束条件第5条“提交到Servlet的参数以JSON格式提交”就是因为第一次生成的form表单提交是普通参数格式,后来改统一了才加进去的。
建议每一轮对话有独立的专注主题。不要在一轮对话里又要设计表、又要建页面、又要写Servlet。把项目拆成“表结构设计”、“登录注册”、“商品管理”、“入库功能”、“出库功能”、“库存查询”等独立任务,每个任务一轮对话,生成完就测,测完再开下一轮。这样万一出问题,定位也快。
数据库设计是底线,一定自己把关。AI生成表结构会倾向于“每个业务概念都给一张表”,有时候会多出很多冗余表;你需要根据MVP原则自己删掉不需要的表。表结构一旦定下来,后续生成的功能模块代码都围绕它转,改起来最贵。
版本管理别偷懒。哪怕是一个人开发,也建议从第一天就初始化一个Git仓库。每跑通一个模块就提交一次,多模块联调搞砸了还能回来。课设最怕的是什么?代码改到一半找不到原来的可用版本,只能从头再来。
我在实际操作中最深的体会是:提示词开发最关键的能力,不是打字,也不是会“魔法咒语”,而是把模糊需求变明确的能力。你越能清晰地描述你的业务、边界、约束和验收标准,AI的输出质量就越高,你拿到手里的半成品也就越接近可用状态。这种能力不挑技术栈、不挑领域,几乎是可以迁移到任何工作场景里的元能力。
蓝动记这个项目的代码和提示词,我目前都归档在本地Git仓库里。后续如果有精力,会把其中通用性最强的提示词部分整理成一个更通用的模板,放到自己的专栏里,方便有需要的人直接取用。这个项目的最大意义不是代码本身——毕竟进销存源码网上多得是——而是“如何一步步拆解需求、设计边界、沉淀工具,最终提高自己产出效率”的完整方法论。
最后分享一个这段时间最深的感受:技术圈永远在变,今天流行的框架明天可能就被替代,但“把问题想清楚、把需求写明白、把边界定好”这件事,永远不会过时。工具是放大器,而真正决定产出质量的,始终是使用工具的人脑子里有没有那张清晰的蓝图。