☰
JavaWeb网上书店系统从零跑通:Servlet+JSP+JDBC避坑指南
2026/10/18 22:06:15 网站建设 项目流程

简介:这是一份课程设计级的Java网上书店及书店管理系统完整项目源码包,面向计算机专业毕业生、课程设计学生以及需要Java Web实战的初学者,解决从零搭建图书在线销售与后台管理系统的需求。系统分为顾客和管理员双角色,覆盖图书浏览、注册登录、购物车、订单管理及后台图书、用户、订单的增删改查等功能,前端基于Vue和bootstrap,后端采用Servlet+JDBC连接SQL Server数据库,技术栈典型,适合作为毕设或期末大作业。资源共1664个文件,以html/css/js前端页面、java及class后端代码、jpg/png图片素材为主,附带项目说明文档,整体压缩包约25.68MB,目录结构清晰便于直接导入并二次开发。已有536人学习下载,对于需要参考完整业务逻辑与代码实现的学习者而言,具备较高的实用价值。

1. 这门课设为什么年年都有人做,年年都有人翻车

网上书店管理系统大概是 Java 课程设计里出现频率最高的题目之一,几乎每个学校、每一届都在做。你搜到的这个源码包,本质上就是一个标准的 JavaWeb 项目:前台模拟用户逛书店、搜书、加购物车、下单,后台管理图书库存、订单状态和用户信息。技术栈不新,但胜在完整——它把 Servlet、JSP、JDBC、MySQL 这些课内学过的东西全部串了起来,比单纯写一个图书管理 CRUD 有说服力得多。

但恰恰因为太常见,翻车率也高。我见过太多人拿到源码后第一步就卡住了:JDK 版本和 Tomcat 不匹配、MySQL 密码没改对、项目编码乱成一团、数据库脚本导不进去,最后连登录页都打不开。这篇笔记就是帮你把这条路走通——从技术选型讲起,到环境搭建、核心模块实现、常见坑排查,最后给你几个让答辩加分的小技巧。不管你是打算拿这套源码直接改,还是想自己从零搭一个,照着下面的思路走,能把大量无意义的调试时间省下来。

2. 先看懂这套系统的技术选型和架构,再动手改代码

2.1 为什么课程设计普遍选 Servlet + JSP,而不是 Spring Boot

你拿到的这套源码大概率是 Servlet + JSP + JDBC 的经典三层架构,而不是 Spring Boot。这不是作者保守,而是课程设计这个场景的特点决定的。大多数高校的 Java 课程设计大纲还停留在 Servlet + JSP 阶段,Spring Boot 虽然在工业界普及,但教学大纲往往是滞后的。用 Servlet 写,代码里能清楚看到请求怎么进来、参数怎么取、业务逻辑怎么组织、结果怎么跳转,老师检查代码和答辩提问时,每个环节都能对上知识点。

另一个现实原因是:Spring Boot 项目的工程结构对课设来说反而太复杂。Maven 依赖管理、自动配置、内嵌 Tomcat,这些东西对于只学过 Java SE 和数据库的学生来说,黑匣子太多了。答辩时老师问一句“Spring Boot 是怎么帮你启动 Tomcat 的”,容易答不上来。而 Servlet + JSP 的方案,所有代码路径都是你自己写的,每一行都能解释清楚,这本身就是课程设计拿高分的关键——不是代码多高级,而是你能说清楚它怎么跑起来的。

2.2 这套代码的典型分层结构:Model、Dao、Service、Servlet

展开源码包之后,正常情况下你会看到这样的包结构,这也是 JavaWeb 课设的标准分层:

src/ ├── com.bookstore.model # 实体类:User, Book, Order, OrderItem, CartItem ├── com.bookstore.dao # 数据访问层:UserDao, BookDao, OrderDao ├── com.bookstore.dao.impl # Dao 接口实现,里面是 JDBC 代码 ├── com.bookstore.service # 业务层接口:处理登录逻辑、下订单事务 ├── com.bookstore.service.impl # 业务实现 ├── com.bookstore.servlet # 控制器层:接收请求、调用 service、跳转 JSP ├── com.bookstore.util # DBUtil 数据库连接工具类 └── com.bookstore.filter # 编码过滤器、登录拦截过滤器

对应的 web 目录下是 JSP 页面,按功能拆成前台页面和后台管理页面两块。前台包括首页、图书列表、图书详情、购物车、结算页;后台包括登录页、图书管理、订单管理、用户管理。

这个分层的核心思路是:Servlet 不直接写 SQL,它调 Service 接口;Service 不直接碰 Connection,它调 Dao 接口;只有 Dao 的实现类里才有 JDBC 代码。按这个规矩写,出了一个 bug,你能很快定位到是哪一层出了问题。比如下单后库存没扣,你不需要去翻 JSP,直接去 OrderDaoImpl 里查 update 语句就行。

我给你的建议是:跑通项目后,先不急着改功能,把 DBUtil.java、LoginServlet.java、BookDaoImpl.java 这三个文件完整读一遍。它们分别代表了连接数据库、接收请求、操作数据三条线。把这三条线看懂,这套系统的代码对你来说就没有任何秘密了。

2.3 数据库连接串的玄学:你第一个要改的地方

几乎所有拿到源码的人,第一个报错都出在数据库连接配置上。源码里一般会有一个 db.properties 或者 DBUtil.java,里面写死了数据库地址和账号密码:

// DBUtil.java 关键代码 private static String url = "jdbc:mysql://localhost:3306/bookstore?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"; private static String username = "root"; private static String password = "123456";

这三个值必须和你本地环境一致。常见问题是密码不是 123456、不知道怎么看端口是不是 3306、MySQL 版本是 8.x 导致连接报错。连接串里的serverTimezone=Asia/Shanghai是给 MySQL 8.x 用的,少了它经常报时区错误。characterEncoding=utf8是保证中文不会变成问号的关键。

如果你用的是 MySQL 5.7,这段配置没问题直接能用;如果是 8.0+,还需要确认 pom.xml 或者 lib 目录里的 JDBC 驱动 jar 包是mysql-connector-java的 8.x 版本,否则驱动类名都对不上。驱动 jar 版本不对,报的错是ClassNotFoundException: com.mysql.jdbc.Driver,这个时候别怀疑代码,去换驱动版本就行。

3. 从零把项目跑起来:环境匹配、导入步骤与最小验证

3.1 版本匹配表:JDK、Tomcat、MySQL 怎么选不吵架

很多项目跑不起来的根源不是代码有问题,而是环境版本不匹配。JavaWeb 课设在这方面的血泪经验特别多。先给出一张我常用的版本匹配表,照这个搭配踩坑最少:

组件推荐版本说明
JDK1.8 或 8课设代码基本都是 JDK 8 语法,Lambda 都用得少
Tomcat8.5 或 9.0能配合 JDK 8,支持 Servlet 3.1/4.0
MySQL5.7 或 8.08.0 记得配 serverTimezone
Eclipse / IDEA任意较新版本建议直接用 IDEA,社区版就够
JDBC 驱动5.1.49(配 MySQL 5.7)或 8.0.x(配 MySQL 8.0)驱动版本必须和 MySQL 大版本匹配

注意一个容易忽略的点:Tomcat 10 和 Tomcat 9 的包名不一样。Tomcat 10 把javax.servlet改成了jakarta.servlet,如果你的课设代码里 import 的是javax.servlet.http.HttpServlet,放到 Tomcat 10 上直接编译不过。所以拿到源码先看一眼 import 语句,是 javax 就老老实实用 Tomcat 8.5 或 9.0。

3.2 IDEA 导入项目的完整操作路径

用 IDEA 导入这类不带 Maven 的 Web 项目,很多人第一步就迷路了。正确做法不是 Open 整个文件夹,而是按下面这个路径走:

第一步,用 IDEA 的File -> New -> Project from Existing Sources,选中源码根目录,然后一路 Next,在第三个页面选择Create project from existing sources而不是Import project from external model。

第二步,项目导入后,打开File -> Project Structure,在Project里把 SDK 选成 1.8,在Libraries里把 lib 目录下的 jar 包全部加进去,主要是 mysql-connector 和 jstl 相关的 jar。没有这一步,代码里所有 import 都会标红。

第三步,在Artifacts里确认打包方式是Web Application: exploded,Output Layout 里要有 lib 下的 jar 包。这一步不配置,部署到 Tomcat 时会出现ClassNotFoundException,但是代码编译却不报错,排查起来很隐蔽。

第四步,配置 Tomcat:Run -> Edit Configurations -> + -> Tomcat Server -> Local,Application server 选你本地 Tomcat 的安装目录,Deployment 里把刚才的 artifact 加进去,Application context 建议设成/bookstore。这样访问地址就是http://localhost:8080/bookstore。

3.3 导入数据库脚本的两个关键动作

源码包里一般带一个bookstore.sql或类似的数据库脚本。这个文件不是用记事本打开复制粘贴那么简单,正确姿势是:

# 在 MySQL 命令行或 Navicat 查询窗口中执行 # 先建库,再导入数据 CREATE DATABASE IF NOT EXISTS bookstore DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE bookstore; SOURCE /你的绝对路径/bookstore.sql;

用 Navicat 的话,右键连接 -> 运行 SQL 文件,选择脚本文件执行即可。执行完之后重点检查三张表:book表里有没有图书数据,user表里有没有管理员账号,order表是不是空的。如果book表是空表,说明脚本导入失败或脚本本身没包含数据,后面登录进去后台一本书都看不到,你会误以为程序 bug 了,其实是数据没进去。

检查数据很简单,在查询窗口执行SELECT COUNT(*) FROM book;,返回数字不为 0 就说明有数据。

3.4 部署后第一个要验证的路径:用户登录

项目跑起来之后,不要先去点乱七八糟的功能,第一步验证路径就走用户登录。因为登录涉及数据库查询、密码匹配、Session 写入、页面跳转四个核心环节,任何一个环节有问题,都会在登录这里暴露出来。

正常流程是:打开浏览器访问首页,点击登录按钮,输入源码说明文档里的默认账号密码,登录成功后跳转到首页并显示用户名。如果这一步通了,说明 Tomcat 部署、数据库连接、JSP 渲染、Filter 过滤器这几条链路全部是通的。如果这一步都走不通,后面所有功能都不用测试,先把登录修好再说。

很多源码在登录成功后会往 Session 里塞一个 user 对象,同时用 Filter 拦截未登录用户访问后台页面。所以如果你直接访问后台管理地址被重定向回登录页,这不算 bug,是逻辑本来就该这样。源码说明文档里一般会写明管理员账号,找不到的话直接在user表里搜admin或role=1的用户,把那行记录的密码改成你自己的再登录。

4. 核心模块逐个拆解:从数据库表设计到下单事务

4.1 五张核心表的设计逻辑,看完你也能从零建

这套系统的数据库表设计是有规律可循的。网上书店的领域模型说白了就五个概念:用户、图书、购物车、订单、订单项。购物车在数据库里通常不建表,因为购物车是临时数据,放在 Session 里就够了,但订单必须有表,因为订单是持久化数据,要留档、要查历史。

典型的建表语句长这样:

-- 用户表 CREATE TABLE `user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL UNIQUE, `password` VARCHAR(100) NOT NULL, `role` INT DEFAULT 0, -- 0 普通用户,1 管理员 `phone` VARCHAR(20), `address` VARCHAR(200) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 图书表 CREATE TABLE `book` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `author` VARCHAR(50), `price` DECIMAL(10,2), `stock` INT DEFAULT 0, `category` VARCHAR(50), `cover` VARCHAR(255), -- 封面图片路径 `description` TEXT ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 订单表 CREATE TABLE `order` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `user_id` INT NOT NULL, `total_price` DECIMAL(10,2), `status` INT DEFAULT 0, -- 0 未发货,1 已发货,2 已完成 `create_time` DATETIME, FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意三点:第一,order是 MySQL 的保留字,建表时要么加反引号,要么把表名改成orders,很多源码直接裸写order,导入时报语法错误,这就是原因之一。第二,价格字段必须用DECIMAL,用FLOAT会出现 0.1 + 0.2 不等于 0.3 的经典问题,后面算订单总额时价格对不上就怪这个。第三,外键约束要加上,课设答辩时老师通常会问“订单和用户是什么关系”,有外键比没有外键更容易解释。

4.2 图书列表的分页查询:页面一页页翻背后的 SQL 逻辑

图书列表页是前台访问量最大的页面。如果图书只有二三十条,一次性查出来没问题,但要做得分页查询,也就是每页显示固定条数,底部有页码可以翻。分页这个点在答辩时被问到的概率非常高,你要能讲清楚它的 SQL 逻辑。

// BookDaoImpl.java 分页查询关键代码 public List<Book> findByPage(int pageNum, int pageSize) { String sql = "SELECT * FROM book LIMIT ?, ?"; // 计算偏移量:第 1 页从 0 开始,第 2 页从 pageSize 开始 int offset = (pageNum - 1) * pageSize; return queryList(sql, offset, pageSize); } public int count() { String sql = "SELECT COUNT(*) FROM book"; // 返回图书总数,供计算总页数用 }

参数说明:pageNum是当前页码,前端页面传递过来;pageSize是每页显示条数,一般固定为 8 或 10。LIMIT ?, ?第一个参数是偏移量,第二个参数是取多少条。比如第 3 页每页 10 条,偏移量就是 (3-1)*10=20,也就是说跳过前 20 条,取第 21 到第 30 条。

这里有个容易踩的坑:如果页码从 1 开始传,一定要记得偏移量是(pageNum - 1) * pageSize,把减 1 写成pageNum * pageSize会导致第一页和第二页显示的数据重叠或跳条。总页数的计算也有讲究,正确公式是(int) Math.ceil(totalCount * 1.0 / pageSize),用整数除法的话有余数时页数会少一页。

4.3 购物车的两种实现方案:Session 存储和数据库存储

图书详情页点“加入购物车”,背后逻辑是往当前用户的购物车里塞一本书。这个购物车数据放哪里,是有讲究的,也是答辩时老师喜欢问的点。

两种常见方案对比:

方案实现位置优点缺点适用场景
Session 购物车HttpSession无需建表,实现简单关浏览器丢数据,无法跨设备课设、小规模演示
数据库购物车cart_item 表持久化,可跨设备多一张表,增删改查代码变多商业网站

课设源码大多用 Session 方案,因为简单直观。实现思路是:Session 里存一个Map<Integer, CartItem>,key 是图书 ID,value 是购物车条目(包含书的信息和数量)。加入购物车时,先看 Map 里有没有这本书,有就把数量 +1,没有就新建一条。这个逻辑写下来大概二十行代码,但承载了“购物车”整个概念。

// 加入购物车的核心逻辑 public void addToCart(HttpSession session, Book book) { // 从 Session 取出购物车,第一次访问时创建 Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("cart"); if (cart == null) { cart = new HashMap<>(); session.setAttribute("cart", cart); } // 判断该商品是否已在购物车中 CartItem item = cart.get(book.getId()); if (item == null) { cart.put(book.getId(), new CartItem(book, 1)); } else { item.setQuantity(item.getQuantity() + 1); } }

逻辑说明:第一步从 Session 拿购物车,没有就新建一个。第二步拿着图书 ID 去 Map 里找,找不到说明是新商品,数量设为 1;找到了说明已经加过,把数量递增。这个模式本身就是面试题“如何用 Map 实现购物车”的标准答案,理解了你就能自己扩展:修改数量就是把setQuantity改成新值,删除商品就是cart.remove(bookId)。

4.4 下单的事务问题:库存扣减和订单创建必须同时成功

下单是整个系统里唯一的“写多张表”的操作。用户点击提交订单后,后端要做三件事:往订单表插一条记录、往订单项表插入商品明细、扣减图书表的库存。这三件事任何一件失败,其它两件都得回滚,不然就会出现订单建了但库存没扣,或者库存扣了但订单没建的数据不一致。

JDBC 里开启事务的代码模式是固定套路,源码里一般放在 service 层而不是 servlet 层:

// OrderServiceImpl.java 提交订单 public boolean createOrder(Order order, List<CartItem> items) { Connection conn = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false); // 关闭自动提交 OrderDao orderDao = new OrderDaoImpl(); orderDao.insert(conn, order); // 1. 插入订单表 OrderItemDao itemDao = new OrderItemDaoImpl(); for (CartItem item : items) { itemDao.insert(conn, order.getId(), item); // 2. 插入订单项 bookDao.decreaseStock(conn, item.getBookId(), item.getQuantity()); // 3. 扣库存 } conn.commit(); // 全部成功才提交 return true; } catch (Exception e) { conn.rollback(); // 任何一步失败,全部回滚 e.printStackTrace(); return false; } finally { DBUtil.close(conn); // 释放连接 } }

这段代码是课设里“含金量”最高的部分,因为事务是 JDBC 里最重要的概念之一。注意每个 Dao 方法都要接收Connection conn参数,原因在于事务必须基于同一个 Connection。如果这里每个方法内部都去DBUtil.getConnection(),三个方法各自用一条连接,事务就失效了——每一条连接的提交和回滚互不知情。这个细节也是老师最爱设的陷阱问题。

另外建议你在测试时故意制造一次失败:把扣库存的 SQL 里的表名写错,再下一次单,你会发现订单没有被创建。这就是事务天然的回滚效果,答辩时可以当场演示。

5. 避坑排查:部署这个课设最常见的 6 个疑难杂症

5.1 页面中文全部变成问号:编码过滤器没生效或位置不对

现象是浏览器打开的页面全是???,或者往数据库里插入的中文数据变成问号。

原因有三个层次:JSP 页面本身不是 UTF-8 编码、Servlet 接收请求时没有设置request.setCharacterEncoding("UTF-8")、数据库连接串没有characterEncoding=utf8。最常见的是第二个,Tomcat 8 默认请求编码是 UTF-8,但前提是你得告诉它“现在按 UTF-8 解码”,不然表单提交的中文到后端就乱了。

解决方式是在 web.xml 里配置一个编码过滤器,这在源码里一般已经写好了:

<filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.bookstore.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

注意/*这个匹配路径,它表示拦截所有请求。如果把/*写成了/,过滤器只会匹配根路径,所有页面请求都不会经过过滤器,中文照样乱码。排查时先确认过滤器有没有生效,最简单的方法是在过滤器代码里加一行System.out.println("EncodingFilter executed");,控制台打印了就说明拦截到了。

5.2 Tomcat 启动报错ClassNotFoundException:jar 包在编译期有、运行期丢了

现象是 IDEA 代码区没有红叉,编译能通过,但启动 Tomcat 时控制台报ClassNotFoundException: com.mysql.jdbc.Driver。

原因是 IDEA 的编译路径和运行路径是分开的。jar 包只加进了编译的 Libraries,但没有打进 Artifacts 的 Output 目录。运行时 Tomcat 去项目部署目录的WEB-INF/lib下找驱动,找不到就报类不存在。

解决方式是进入Project Structure -> Artifacts -> Output Layout,在左侧Available Elements里找到你的 jar 包,右键选择Put into /WEB-INF/lib。把这个动作做完,重启 Tomcat 就好了。这个错误很隐蔽,因为代码编辑器不报错,只在运行时报,很多新手卡在这里一个多小时。

5.3 MySQL 8.x 连接报时区错误:连接串缺参数

现象是启动项目后,第一次访问数据库相关页面就报错:The server time zone value '?й??????' is unrecognized或类似的一长串。这是 MySQL 8.x 的严格时区检查导致的问题,5.7 没有这个机制。

解决方式是在 JDBC 连接串里明确指定服务器时区:

// 完整连接串写法 String url = "jdbc:mysql://localhost:3306/bookstore?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true";

这里有三个参数是 MySQL 8.x 环境下的“保命三件套”:useSSL=false是跳过安全证书验证,不加的话会报 SSL 连接警告;serverTimezone=Asia/Shanghai让服务器时区明确为东八区;useUnicode=true&characterEncoding=utf8保证中文数据传输不乱码。如果你不想改连接串,另一个方案是在 MySQL 配置文件my.ini里加default-time-zone = '+08:00'然后重启 MySQL 服务,但改连接串更快更安全。

5.4 数据库导入脚本报Syntax error:要么缺反引号,要么少了库

现象是执行.sql文件时报语法错误,脚本卡住一条都执行不进去。

原因通常是两种:第一,脚本里写了USE bookstore;但你本地还没有这个数据库,先建库再执行脚本顺序错了;第二,脚本里某些表或字段名撞了 MySQL 关键字,最典型的是order(订单表),需要反引号包起来。

排查方法是把脚本第一段 CREATE 语句拿出来单独执行,看报错位置是不是在order表附近。如果是,把表名改成orders也是一种选择,但要注意同时改所有 SQL 语句里对这张表的引用,工作量比较大。建议尽量保持原库名,把建表语句里order改成`order`(加反引号),一行的事,不用全局改。

5.5 登录失败但没报错:未查询到任何数据直接返回了

现象是表单提交登录后,页面提示“用户名或密码错误”,控制台没有任何异常,数据库里明明有这条用户记录。

原因定位思路:先看用户表里的密码存的是什么形式。如果源码说明里写密码是明文,那有可能是你 Navicat 里改过密码但没保存,或者用户名带了空格。如果说明文档里写了密码经过 MD5 处理,那你就不能直接在表里塞一个明文密码,得先把密码 hash 一下。

解决方式:用 Navicat 打开user表,直接复制一个已有账号,把用户名改成你自己的,密码保持原样,再用它登录。这样能排除密码加密方式不一致的问题。如果这能登录,说明问题就出在你手改密码时格式不对。如果还不能登录,那就去UserDaoImpl.java的登录查询方法里加一行打印,把 SQL 语句打出来,看拼出来的 SQL 是什么,多半是谓词条件没拼对。

5.6 修改代码后刷新页面不生效:热部署没开

现象是改了 JSP 页面或者 Servlet 代码,刷新浏览器没变化,重启 Tomcat 才生效。

原因是 IDEA 默认对 JSP 修改会立即生效,但对 Java 类文件修改需要重新编译并重新部署。如果没开启热部署,Tomcat 还在跑旧的 class 文件。

解决方式是进入Run -> Edit Configurations -> Tomcat Server -> Deployment,选中部署项,把On frame deactivation和On update action都设为Update classes and resources。这样改完 Java 代码按Ctrl + F9重新编译,Tomcat 会自动加载新 class,不用重启。但这个设置偶尔不灵,比如新增了方法签名变化较大时,老老实实重启 Tomcat 最靠谱。

6. 答辩和二次开发:让这套课设从“能跑”变成“能讲”

到了这个阶段,项目已经能跑通了,但距离答辩拿高分还有几步路。课程设计的评价标准从来不只是“能不能运行”,而是“你能不能把系统讲清楚”。有三个操作我建议你必做,能在短时间内显著提升答辩表现。

第一个必做操作是给项目加上 MD5 密码加密。现在的源码大概率是明文存密码,你先在UserDaoImpl的注册方法里把密码处理一下:

// 密码加密工具类 public class MD5Util { public static String md5(String source) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] result = md.digest(source.getBytes("UTF-8")); // 将字节数组转成十六进制字符串 StringBuilder sb = new StringBuilder(); for (byte b : result) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (Exception e) { throw new RuntimeException(e); } } }

然后把登录和注册两处对密码的处理都包一层MD5Util.md5(password),数据库里存的 password 字段就变成 32 位哈希值了。答辩时老师问“用户密码安全你考虑了吗”,这个功能就是最好的回应。注意一个边界点:如果你之前用明文登录过,数据库里的老数据要重新注册一遍或手动把哈希值写进去,否则新旧密码格式不一致会登录失败。

第二个必做操作是给图书列表加一个关键字搜索。改起来成本很低,只需要在BookDaoImpl里加一个方法:

// 按书名模糊查询,同时支持分页 public List<Book> searchByName(String keyword, int pageNum, int pageSize) { String sql = "SELECT * FROM book WHERE name LIKE ? LIMIT ?, ?"; // 使用 LIKE 模糊匹配,前后加 % 表示包含该关键字 String pattern = "%" + keyword + "%"; int offset = (pageNum - 1) * pageSize; return queryList(sql, pattern, offset, pageSize); }

页面端在图书列表页顶部加一个输入框和一个提交按钮,把 keyword 传到 Servlet,Servlet 调用searchByName并回传结果即可。这个功能加完之后,你可以在答辩时演示“输入‘Java’搜索,只显示相关书目”,这一下子就比普通的“全表展示”有了区分度。

第三个必做操作是给后台订单管理页加一个“受理”按钮。书店管理员看到新订单后,点一下按钮把订单状态从“未发货”改成“已发货”。实现方式是在订单列表页每个订单后面加一个链接,跳转到OrderServlet?action=deliver&id=订单号:

// 修改订单状态的 SQL public void updateStatus(int orderId, int status) { String sql = "UPDATE `order` SET status = ? WHERE id = ?"; // status: 0 未发货 -> 1 已发货 -> 2 已完成 }

这个功能的代码量不大,但它在业务上是完整的:用户下单、管理员发货、状态流转。答辩时老师问“系统怎么体现管理员角色和普通用户角色的区别”,你就演示这个页面——普通用户进不了后台,管理员能看订单还能改状态,整个权限模型就立起来了。

最后说一个答辩技巧层面的经验:与其把源码里所有功能都讲一遍,不如拿一个功能讲深。我见过很多同学一上来就说“这个系统有用户模块、图书模块、订单模块、购物车模块”,然后每个功能停留在一句话,老师听完毫无印象。反过来,你只讲“购物车是怎么设计的”,把 Session 存放、数据结构、数量修改、下单时怎么把购物车数据变成数据库记录,这一条线讲清楚,效果远好于面面俱到。这门课设的价值本来就不在于系统有多强大,而是你用 Java 把一个完整的业务链条打通了——这个能力才是你真正带得走的东西。希望这篇笔记能帮你在课设这条路上少走几步弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询