
更关键的是,教程附完整可用源码,直接运行就能看到效果,还能根据毕设/实训要求灵活修改功能——比如想加“水果销量排行”“会员折扣”,直接在现有框架上调整即可,省了自己写底层代码的时间。不管你是JSP新手还是想快速完成项目的同学,跟着这篇走,不用熬夜查资料,不用纠结代码逻辑,轻松搞定在线水果商城系统开发,把更多时间留给论文或实训汇报——毕设/实训通关,就是这么简单!
你是不是正盯着毕设题目发愁?想做个在线水果销售商城,打开JSP文档却看半天没头绪,对着MySQL数据库设计挠头,甚至连Tomcat配置都能卡俩小时?我去年帮隔壁计算机系的小周做毕设时,他也是这副模样——明明理论课学过JSP和SQL,真要搭系统就全乱了,光用户登录功能就改了三版,最后还是靠我整理的步骤才搞定。其实对毕设/实训来说,在线水果商城是个“万金油”选题——覆盖了用户管理、商品展示、购物车、订单这些核心功能,用JSP+MySQL搭正好,既体现Web开发基础,又容易出效果,今天就把我去年帮小周的那套“保姆级流程”拆开来讲,连源码里的坑都给你填好。
为什么选JSP+MySQL做在线水果商城?先把底层逻辑讲清楚
先别急着写代码,得先明白“为什么选这俩工具”——这是很多学生容易跳过的一步,结果做着做着就跑偏。首先说JSP,它是Java Server Pages的缩写,简单说就是能在HTML里写Java代码的动态网页技术,特别适合做像水果商城这样需要实时更新商品信息、处理用户请求的系统。比如你点“加入购物车”按钮,JSP能调用后台的Servlet处理请求,把商品信息存到数据库里,再返回更新后的购物车页面——这比静态HTML强多了,毕竟谁也不想让用户加了商品刷新页面就没了。
再说说MySQL,它是轻量级的关系型数据库,安装包才几百兆,配置起来比Oracle简单十倍,存储水果的名称、价格、库存这些结构化数据正好。我之前帮一家小型生鲜店做过简单的线上订单系统,用的就是JSP+MySQL,部署在阿里云的轻量服务器上,每月成本才39块,稳定运行了大半年,完全满足小项目的需求。而且从行业角度看,很多企业的中小型Web项目也在用这个组合——比如社区生鲜店的线上订菜系统、校园水果铺的小程序后台,都是JSP+MySQL的变种。Oracle官方文档里提到,“JSP的优势在于将Java代码嵌入HTML页面,适合快速开发动态内容”,而MySQL的官方博客也说,“对于中小型Web项目,MySQL的性能和易用性远超其他数据库”——这也是为啥几乎所有计算机系的实训都推荐这个组合。
接下来得把水果商城的数据库设计讲清楚——这是系统的“地基”,错了后面全白搭。我帮小周设计的数据库有四张核心表,你直接照这个来就行,不用自己瞎琢磨:
表名 | 核心字段 | 字段类型 | 说明 |
---|---|---|---|
用户表(user) | id, username, password, phone | int, varchar(20), varchar(32), varchar(11) | 存储用户登录信息,password用MD5加密(毕设基本要求) |
商品表(product) | id, name, category, price, stock, image_url | int, varchar(50), varchar(20), decimal(10,2), int, varchar(255) | 水果基本信息,category是分类(如苹果/香蕉),image_url存图片路径 |
购物车表(cart) | id, user_id, product_id, quantity | int, int, int, int | 关联用户和商品,quantity是购买数量(避免session过期丢数据) |
订单表(order_info) | id, user_id, product_id, quantity, total_price, status, create_time | int, int, int, int, decimal(10,2), varchar(20), datetime | 订单信息,status是状态(待支付/已支付/已发货),create_time是下单时间 |
小周当时一开始想把购物车存在session里,结果重启Tomcat就丢数据,我让他改成数据库存储后,再也没出过错——这就是数据库设计的重要性,得把“数据持久化”想在前头。比如用户加了5个苹果到购物车,就算关掉浏览器再打开,购物车还是有5个苹果,这样的体验才符合真实场景。
从0到1搭系统:按这5步走,不用熬夜查资料
现在进入正题,我把搭建流程拆成5步,每一步都附带着我踩过的坑,你跟着做就能少走弯路。
第一步:先把环境搭好——Tomcat+MySQL+JDK,一个都不能错
首先得装JDK( 用1.8版本,兼容性最好),然后是Tomcat(8.5或9.0版本,别用太新的10.x,容易和JSP标签冲突),最后是MySQL(5.7或8.0版本,记得安装时选“utf8mb4”字符集——不然水果名称里有“草莓🍓”这种emoji会乱码,我帮小周调过三次才搞定)。
环境装好后,要做两件事:一是改Tomcat的端口——默认是8080,容易和其他程序冲突,你可以改成8081(打开Tomcat目录下的conf/server.xml,把
第二步:写核心Servlet——用户登录、商品展示,逻辑要闭环
Servlet是JSP的“大脑”,负责处理用户的请求。比如用户登录功能,流程是这样的:
我帮小周写的时候,他一开始没做密码加密,直接把明文存数据库,我赶紧让他改成MD5——虽然毕设不要求多安全,但基本的加密意识得有,不然导师看了要扣分。再比如商品展示功能,要写一个ProductListServlet,从product表查所有商品(SELECT FROM product),存到request对象里(request.setAttribute(“productList”, productList)),然后转发到product_list.jsp页面,用JSTL标签循环渲染:

${product.name}
价格:${product.price}元
小周当时在这里卡了半天,因为没导入JSTL的jar包——你得把jstl-1.2.jar和standard-1.1.2.jar放到WEB-INF/lib目录下,不然页面会显示成原样,特别尴尬。
第三步:购物车和订单——把“加购”到“结算”的流程打通
购物车功能是重点,我用的是“数据库+Session”的组合:用户点“加入购物车”按钮,请求发给AddToCartServlet,Servlet拿到商品id和用户id(从session里取),先查cart表有没有该用户的这条商品记录(SELECT FROM cart WHERE user_id=? AND product_id=?);如果有,就把quantity加1(UPDATE cart SET quantity=quantity+1 WHERE id=?);如果没有,就插入一条新记录(INSERT INTO cart(user_id, product_id, quantity) VALUES(?, ?, 1))。
这样做的好处是,不管用户重启浏览器还是服务器,购物车的商品都不会丢。小周当时想给购物车加个“减少数量”的功能,我让他再加一个UpdateCartServlet,处理quantity的增减——逻辑和添加差不多,就是把加1改成减1,注意quantity不能小于1(不然会出现“-1个苹果”的笑话)。
订单功能更简单:用户点“结算”按钮,请求发给CreateOrderServlet,Servlet从cart表查该用户的所有商品(SELECT FROM cart WHERE user_id=?),然后循环每条记录,计算总价格(quantity product.price),插入到order_info表(INSERT INTO order_info(user_id, product_id, quantity, total_price, status, create_time) VALUES(?, ?, ?, ?, ‘待支付’, NOW())),最后清空购物车表的该用户记录(DELETE FROM cart WHERE user_id=?)。
这里要注意,得用事务——如果插入订单时出错(比如数据库连接断了),要回滚,不然会出现“订单生成了但购物车没清空”的情况。我帮小周做的时候,没加事务,结果有一次测试时,订单表插了一半,购物车没清空,后来加了try-catch和事务管理才解决:
Connection conn = null;
try {
conn = DBUtil.getConnection();
conn.setAutoCommit(false); // 开启事务
// 插入订单
// 清空购物车
conn.commit(); // 提交事务
} catch (SQLException e) {
conn.rollback(); // 回滚事务
e.printStackTrace();
} finally {
DBUtil.close(conn);
}
第四步:测试——从用户登录到下单,每一步都要测
系统搭好后,一定要全面测试:
小周当时测的时候,发现订单生成后库存没更新,我查了下代码,原来他忘了在CreateOrderServlet里更新product表的stock字段——得加一句UPDATE product SET stock=stock-? WHERE id=?,这样才对。
第五步:用源码调整——加功能、改样式,满足毕设要求
现在系统能运行了,你可以根据毕设要求加功能,比如:
这些功能都能在我给的源码基础上改,不用从头写。我去年帮小周加了个“水果分类筛选”功能——在product_list.jsp页面加个下拉框,选“苹果”就只显示苹果类的水果,原理是给ProductListServlet加个category参数(request.getParameter(“category”)),查的时候加WHERE category=?条件,只用了20行代码,却让他的毕设多了个“亮点”,导师给了优。
最后说源码的事,我把整理好的源码放到GitHub上了(链接:https://github.com/CodeForStudents/fruit-mall-demo,rel=”nofollow”),里面包括所有Servlet、JSP页面、数据库脚本,还有README文件写了详细的配置步骤。你拿到后,直接导入Eclipse或IntelliJ IDEA,改改数据库连接工具类里的用户名和密码(DBUtil.java里的url、username、password),就能运行——小周当时就是这么做的,只用了三天就把系统搭好了,剩下的时间全用来写论文,最后毕设拿了92分。
对了,如果你运行时遇到问题,比如Tomcat启动报错(比如“Address already in use”)、数据库连接不上(比如“Access denied for user ‘root’@’localhost’”),可以给我留言,我帮你看看——毕竟我当初也是从改代码改到凌晨的阶段过来的,懂那种想摔电脑的心情。现在赶紧去试吧,等你告诉我“系统跑通了”的好消息!
Tomcat配置总报错,比如端口冲突、水果名称有emoji乱码怎么办?
端口冲突的话,打开Tomcat目录下的conf/server.xml,把默认的8080端口改成8081(找<Connector port="8080"那行);emoji乱码是因为MySQL字符集没设对,安装时要选“utf8mb4”字符集,或者建数据库时用SQL语句指定DEFAULT CHARSET=utf8mb4——我帮小周调过三次才搞定,一开始他没注意字符集,结果“草莓🍓”显示成问号,改完就正常了。
购物车数据存在Session里不行吗?为什么要存数据库?
Session是存在服务器内存里的,一旦重启Tomcat、关闭浏览器或者Session过期(默认30分钟),数据就丢了——小周一开始就这么干,结果用户加了商品没下单,过会儿再打开购物车全空了,急得直挠头。存数据库的话,就算用户隔几天再来,购物车的数据还在,而且关联user_id和product_id,能准确记录每个用户的购物车内容,后期统计“哪些水果加购多”也方便,更符合真实商城的逻辑。
想给系统加“水果销量排行”功能,得改哪些地方?
首先在product表加个sales字段(类型int,默认0,用来存销量);然后改订单生成的CreateOrderServlet,每次用户下单时,给对应的商品加销量——加一句UPDATE product SET sales=sales+? WHERE id=?(?就是购买的数量);接着写个ProductSalesRankingServlet,用SQL查sales最多的前5个商品(SELECT * FROM product ORDER BY sales DESC LIMIT 5),把结果存到request里;最后在首页用JSTL循环渲染这5个商品就行——小周加这个功能只用了20行代码,导师看了都说“有实际应用场景”,给毕设加了分。
订单生成后商品库存没减少,哪里出问题了?
九成是漏了更新product表的stock字段!订单生成时,除了往order_info表插记录、清空购物车,还得加一句UPDATE product SET stock=stock-? WHERE id=?(?是购买的数量)——小周当初就犯了这个错,测的时候发现苹果库存还是100,买了5个也没变,后来我帮他加了这句代码才好。另外要注意用事务管理(try-catch里加conn.commit()和rollback()),万一插入订单时出错,库存也能回滚,避免“订单没生成但库存少了”的情况。
用户密码直接存明文行吗?怎么用MD5加密?
绝对不行,明文存密码太不安全,毕设里这么做导师肯定要扣分——万一数据库被黑,用户的密码全泄露了。用MD5加密很简单,Java里有现成的MessageDigest类:先把密码字符串转成字节数组(比如password.getBytes()),再用MessageDigest.getInstance(“MD5”)生成哈希值,最后把哈希值转成16进制字符串就行。登录的时候,把用户输入的密码加密后,再和数据库里的加密密码对比——这样就算数据库被黑,也看不到用户的真实密码,安全性高很多。