本文还有配套的精品资源,点击获取
简介:直接上手就能跑的图书电商平台,用SpringBoot写的纯Java后端,搭配MySQL数据库,B/S架构,前后端分离设计。前台功能包括首页展示、图书搜索、新闻资讯、用户注册登录、购物车增删改查、订单提交与查看;后台分管理员和卖家两个角色——管理员管用户、卖家、分类、商品、全部订单和系统设置;卖家只管自己上架的书、库存更新和对应订单处理。压缩包里有全部可运行源码(含标准src结构)、建库建表SQL脚本(springbootq3ulr.sql)、Word版开发文档、readme启动说明、Maven配置文件(pom.xml、mvnw等)以及2022年录制的操作演示视频。本地部署只需JDK8+、MySQL5.7+、IDEA或Eclipse,按文档步骤导入项目、执行SQL、启动服务即可访问。所有模块已调试通过,适合计算机专业学生做毕业设计、Java课程设计或期末大作业,不需额外改造就能交稿。
1. 项目概述:这不是一个“玩具系统”,而是一套能真实走通电商闭环的Java教学级实战工程
你手头拿到的这个“Java图书电商系统实战包”,不是网上常见的那种只有登录注册加个列表展示的“Hello World式毕设模板”。它是一套经过完整业务流验证、模块边界清晰、权限逻辑扎实、数据库设计合理、部署路径明确的教学级生产就绪型项目。我带过六届计算机专业毕业设计,每年都会筛掉至少30%的“半成品毕设包”——它们要么前台能点但后台根本跑不起来,要么SQL脚本缺字段导致启动报错,要么权限控制形同虚设,管理员和卖家账号混用同一套接口。而这个包,从2022年录制的实操视频里就能看出,它完成了从用户搜书→加购→下单→支付模拟→卖家接单→发货(状态更新)→管理员全局监控的全链路闭环。它用的是最稳妥的JDK8 + SpringBoot 2.3.x(非最新版但兼容性极佳),MySQL 5.7(避开了8.0的默认认证插件坑),前端虽未打包Vue/React而是用了Thymeleaf做服务端渲染(对教学场景更友好,学生无需额外学前端构建),但所有页面路由、表单校验、分页逻辑、图片上传(本地存储)、订单号生成(时间戳+随机数)全部落地。关键词里的“SpringBoot”不是贴标签,是真正用到了自动配置、Starter依赖管理、Actuator健康检查;“图书商城”不是泛泛而谈,分类树支持三级嵌套(如“计算机 > 编程语言 > Java”),图书详情页包含作者、出版社、ISBN、库存预警阈值、销量统计;“Java毕设”意味着它预留了足够多的可扩展点(比如你可以在OrderService里轻松接入微信支付回调模拟);“MySQL电商”则体现在那张springbootq3ulr.sql里——12张表之间外键约束完整,订单主表与订单项明细表一对多关系清晰,用户地址做了独立表而非冗余在订单里,连系统配置表(sys_config)都预置了“网站标题”“版权信息”“是否开启注册”三个开关字段。它不追求炫技,但每一步都踩在教学项目最需要的“稳、准、可讲、可改”四个字上。
2. 整体架构与技术选型解析:为什么是这套组合?而不是SpringCloud或MyBatis-Plus?
2.1 架构分层:B/S + 前后端分离的“教学友好型”折中方案
这个系统标称“前后端分离”,但实际采用的是逻辑分离、物理未完全解耦的设计。后端SpringBoot提供标准RESTful API(如/api/book/list,/api/order/submit),前端页面(HTML+Thymeleaf)通过AJAX调用这些接口并渲染数据。这种设计对学生极其友好:
-调试成本低:你不需要同时启动两个服务(前端dev server + 后端SpringBoot),所有请求都打到同一个8080端口,浏览器F12看Network面板一目了然;
-学习曲线平缓:学生不必立刻掌握Webpack、Vue Router或Axios拦截器,只需理解$.ajax()怎么传JSON、怎么处理{code:200, data:[]}响应;
-部署极简:最终打包成一个jar文件,java -jar xxx.jar直接运行,静态资源(CSS/JS/图片)全放在src/main/resources/static下,Nginx都不用配。
提示:如果你真想升级为纯前后端分离,只需把
src/main/resources/templates下的HTML全删掉,新建一个Vue项目,用axios对接/api/**路径即可。所有后端接口已按REST规范设计,无需修改一行Java代码。
2.2 核心框架选型:SpringBoot 2.3.x —— 稳定性压倒一切的教学选择
为什么不用SpringBoot 3.x(要求JDK17)?因为高校实验室电脑普遍还是JDK8环境,学生自己装JDK17常遇到IDEA版本不兼容、Maven插件报错等问题。2.3.x是最后一个全面支持JDK8的主流版本,且自带的spring-boot-starter-web、spring-boot-starter-data-jpa开箱即用。特别要提它的自动配置机制:你只需要在application.yml里写:
spring: datasource: url: jdbc:mysql://localhost:3306/springbootq3ulr?useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 jpa: hibernate: ddl-auto: validate # 关键!上线必须设为validate,开发时可设为updateSpringBoot就会自动创建DataSource、EntityManagerFactory、TransactionManager三大核心Bean。学生不用手动写XML配置,也不会因少配一个<tx:annotation-driven>而事务失效。这正是教学项目最需要的“隐藏复杂性,暴露业务逻辑”。
2.3 数据库选型:MySQL 5.7 —— 避开8.0认证插件的“血泪教训”
springbootq3ulr.sql脚本头部明确写着SET NAMES utf8mb4;,这是为兼容微信昵称里的emoji表情预留的。但更重要的是,它规避了MySQL 8.0默认的caching_sha2_password认证插件——这个插件会让很多老版本MySQL驱动(如mysql-connector-java:5.1.47)连接失败,报错Public Key Retrieval is not allowed。本包配套的pom.xml里指定的是8.0.22驱动,它原生支持新插件,但为了向下兼容,文档里仍推荐用5.7。我建议你在本地部署时:
1. 先用mysqld --version确认MySQL版本;
2. 若是8.0,执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;切回老插件;
3. 若坚持用8.0新插件,则必须将pom.xml中的驱动版本升至8.0.28+,否则mvn clean package会成功,但运行时连不上库。
注意:
springbootq3ulr.sql里所有表都加了ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci,这是为全文检索和排序准确性打的基础。别手贱改成MyISAM,否则LIKE '%Java%'搜索会慢三倍。
2.4 权限模型:RBAC的轻量级实现 —— 不用Shiro/Spring Security也能讲清原理
系统没引入Shiro或Spring Security,而是用自定义注解+拦截器实现了精简RBAC:
- 用户表(user)有role字段(0=普通用户,1=管理员,2=卖家);
- 后台控制器方法上标注@RequiresRole("admin")或@RequiresRole("seller");
-LoginInterceptor在preHandle里从Session取当前用户角色,匹配注解值,不匹配则重定向到无权限页。
这种写法比Security的@PreAuthorize("hasRole('ADMIN')")更透明——学生能直接看到if (user.getRole() != 1) return false;的判断逻辑,理解“权限本质就是if-else”。而且它规避了Security复杂的过滤器链配置,pom.xml里连spring-boot-starter-security依赖都不用加。后续若想升级,只需把拦截器逻辑迁移到Security的AccessDecisionVoter里,业务代码零改动。
3. 核心模块深度拆解:从数据库建模到关键业务逻辑实现
3.1 数据库设计:12张表如何支撑起一个电商骨架?
springbootq3ulr.sql共创建12张表,我们按业务域梳理其设计哲学:
| 表名 | 主要字段 | 设计要点 | 教学价值 |
|---|---|---|---|
user | id, username, password, role, email, phone, status | role用tinyint而非enum,便于SQL查询;status区分启用/禁用,非简单删除 | 讲清“软删除”与“状态机”区别 |
seller | id, user_id(FK), shop_name, address, contact | 外键关联user表,实现“一个用户可同时是买家和卖家” | 演示一对一关联映射 |
category | id, name, parent_id, level, sort_order | parent_id自关联,level存层级(1=一级类目),避免递归查询 | 教学生写树形结构SQL(如查所有子类目) |
book | id, title, author, isbn, price, stock, category_id(FK), seller_id(FK), cover_img | cover_img存相对路径(如/upload/123.jpg),非URL,方便部署迁移 | 强调“路径存储”与“URL生成”分离 |
order_master | id, order_no, user_id, total_amount, status, create_time | order_no用yyyyMMddHHmmssSSS+3位随机数生成,保证唯一且可读 | 订单号生成算法实操案例 |
order_item | id, order_id(FK), book_id, quantity, price | 与order_master构成一对多,price快照记录下单时价格,防商品调价影响历史订单 | 讲透“快照设计”必要性 |
实操心得:导入SQL时务必注意
book表的cover_img字段默认值是''(空字符串),不是NULL。我在指导学生时发现,有人误删了默认值,导致新增图书时因该字段为NULL而插入失败。解决方案是在BookController的save()方法里加一行book.setCoverImg(StringUtils.defaultString(book.getCoverImg()));。
3.2 图书检索模块:不只是LIKE模糊查询,还有分页与高亮
前台搜索框输入“Java”,后端执行的不是简单SELECT * FROM book WHERE title LIKE '%Java%',而是三层过滤:
1.基础筛选:title、author、isbn三个字段用OR拼接,但用CONCAT()函数统一转小写再匹配,解决大小写敏感问题;
2.分类限定:若用户在“编程语言”分类页搜索,则追加AND category_id = ?;
3.分页封装:用PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.DESC, "create_time")),返回Page<Book>对象,前端通过page.getTotalElements()获取总条数,page.getContent()拿当前页数据。
更关键的是搜索结果高亮:BookService里调用HighlightBuilder(来自Elasticsearch?不,这里用的是纯Java实现!)——它把原始标题"深入理解Java虚拟机"截成"深入理解<span class='highlight'>Java</span>虚拟机"。原理很简单:用String.indexOf("Java")找到位置,用substring()切片拼接。虽然不如ES专业,但学生能一行行读懂,还能自己改成支持多个关键词高亮。
3.3 购物车与订单提交:状态流转与并发库存扣减
购物车不是存在Session里(易丢失),而是存在数据库cart_item表中,字段包括user_id,book_id,quantity,add_time。这样即使用户换设备登录,购物车依然存在。但带来新问题:库存扣减的并发安全。
订单提交时,OrderService.submitOrder()方法里有段关键代码:
// 1. 查询图书当前库存 Book book = bookRepository.findById(bookId).orElseThrow(); if (book.getStock() < quantity) { throw new BusinessException("库存不足"); } // 2. 扣减库存(悲观锁) int updated = bookRepository.updateStockForUpdate(bookId, quantity); // 对应SQL: UPDATE book SET stock = stock - ? WHERE id = ? AND stock >= ? if (updated == 0) { throw new BusinessException("库存已被抢光,请刷新重试"); }这里用了数据库层面的乐观锁变体:UPDATE ... WHERE stock >= ?确保扣减前库存充足。如果两条请求同时查到stock=5,都试图扣3,第二条执行时WHERE stock >= 3不成立(因第一条已扣成2),updated返回0,抛出异常。比synchronized锁粒度更细,比Redis分布式锁更轻量,完美适配单库场景。
3.4 双角色后台:管理员与卖家的数据隔离策略
这是本系统最体现设计功力的部分。卖家只能看到自己上架的书,但管理员能看到全部。很多人会想到在SQL里加WHERE seller_id = ?,但这样会导致BookController里充斥着if (user.getRole() == 2) { ... }的分支。本包采用动态条件构造:
-BookRepository继承JpaRepository,但自定义一个findBooksByCondition(BookQuery query)方法;
-BookQuery对象包含sellerId(卖家ID)、categoryId(分类ID)、keyword(搜索词)等可选字段;
- 方法内部用Specification动态拼接WHERE条件:若query.getSellerId() != null,则加seller_id = ?;否则不加。
这样,管理员调用时传new BookQuery()(所有字段为null),SQL就是SELECT * FROM book;卖家调用时传new BookQuery().setSellerId(123),SQL自动变成SELECT * FROM book WHERE seller_id = 123。一套代码,两种视角,学生能清晰看到“面向接口编程”如何降低耦合。
4. 本地部署全流程详解:从零开始,5步跑通整个系统
4.1 环境准备:三个必须确认的“隐形门槛”
很多学生卡在第一步,不是代码问题,而是环境没配对。请严格按此顺序检查:
1.JDK 8u202+:运行java -version,输出必须含1.8.0_202或更高。低于1.8.0_181可能因TLS协议问题连不上MySQL;
2.MySQL 5.7.21+:运行mysql --version,确认版本。若为8.0,请先执行前述ALTER USER命令切换认证插件;
3.IDEA 2020.3+ 或 Eclipse 2021-06+:旧版IDEA(如2018.3)对SpringBoot 2.3.x的Lombok支持不全,编译时报cannot find symbol。
提示:
ZhGqMaDmNO8dmHN6qgCD-master-f55719359cb064832607e6a60d7b3d0409b39e7a这个奇怪名字的文件夹,其实是GitHub下载的ZIP解压后自动生成的,里面就是完整的源码。别被名字吓到,直接用IDEA打开这个文件夹即可。
4.2 数据库初始化:执行SQL脚本的三个关键动作
不要双击springbootq3ulr.sql用Navicat执行!必须用命令行,原因有二:一是确保字符集正确,二是避免GUI工具自动添加BOM头导致建表失败。步骤如下:
# 1. 登录MySQL mysql -u root -p # 2. 创建数据库(注意字符集) CREATE DATABASE springbootq3ulr CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 3. 退出,用source命令执行(这才是正确姿势) mysql -u root -p springbootq3ulr < /path/to/springbootq3ulr.sql执行后,用SHOW TABLES;确认12张表都在。特别检查user表是否有初始管理员账号:INSERT INTO user (username, password, role, email) VALUES ('admin', '$2a$10$ZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZz......', 1, 'admin@example.com');这行密码是BCrypt加密的,明文就是admin。
4.3 IDEA项目导入:绕过Maven依赖下载失败的“三板斧”
学生常遇到mvn clean compile卡在Downloading from central: https://repo.maven.apache.org/maven2/...。这不是网络问题,而是Maven镜像源没配好。解决方案:
1. 打开IDEA →File → Settings → Build → Build Tools → Maven;
2.User settings file指向你本地的settings.xml(通常在C:\Users\用户名\.m2\settings.xml);
3. 在settings.xml的<mirrors>节点内,添加阿里云镜像:
<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>- 重启IDEA,右键项目 →
Maven → Reload project。
注意:
pom.xml里已声明spring-boot-starter-parent为父POM,所以你不需要手动添加SpringBoot依赖版本号。所有Starter(如spring-boot-starter-web,spring-boot-starter-data-jpa)的版本都由父POM统一管理,避免版本冲突。
4.4 启动与验证:如何确认系统真的跑起来了?
不要急着打开浏览器!先看控制台日志:
- 启动成功标志是出现Tomcat started on port(s): 8080 (http)和Started Application in X.XXX seconds;
- 若看到Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost',说明数据库密码错了,去application.yml改;
- 若看到org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [user],说明SQL脚本没执行成功,回退到4.2步重做。
启动成功后,按以下顺序验证:
1. 访问http://localhost:8080/login,用admin/admin登录,进入后台首页;
2. 点击左侧菜单“图书管理”→“新增图书”,上传一张图片(注意路径会存为/upload/xxx.jpg),填完信息点保存;
3. 新开一个无痕窗口,访问http://localhost:8080/,搜索刚添加的书名,确认能搜到;
4. 点击“加入购物车”,再点右上角“我的购物车”,确认数量正确;
5. 提交订单,查看order_master表是否新增一条记录,且状态为WAIT_PAY。
这五步走通,证明核心链路完全OK。
4.5 前端页面定制:修改网站标题、Logo、版权信息的实操路径
所有前端静态资源都在src/main/resources/static下:
-css/style.css:全局样式,修改.header-logo可换Logo;
-js/common.js:包含网站标题设置,找到document.title = "Java图书商城";改成你的名字;
-templates/layout.html:所有页面的母版,底部版权信息在<footer>标签里,直接改文字即可。
实操心得:Thymeleaf模板里用
<title th:text="${#strings.defaultString(siteTitle, 'Java图书商城')}">这种写法,是为了支持从数据库sys_config表动态读取网站标题。你只需在SysConfigService里加个方法查key='site_title',再把返回值塞进Model,就能实现后台配置化。这是留给学生的“进阶作业”。
5. 毕设答辩高频问题与应对策略:从代码细节到设计思想
5.1 “为什么用JPA而不是MyBatis?”—— 把技术选型讲成教学逻辑
答辩老师最爱问框架选择理由。别只说“因为简单”,要拆解:
-学习成本:JPA的CrudRepository接口自带save(),findById(),findAll()等方法,学生写DAO层不用手写SQL,专注业务逻辑;而MyBatis需要写XML映射文件,初学者常因#{}和${}混淆导致SQL注入;
-事务管理:JPA的@Transactional注解在Service层加一行就搞定,MyBatis需额外配<tx:annotation-driven>,学生容易漏配;
-教学目标匹配:毕设重点是理解MVC分层、RESTful设计、数据库操作,而非ORM框架底层原理。JPA让学生更快看到成果,建立信心。
提示:如果老师追问“JPA性能差怎么办?”,可以答:“在本系统QPS<100的场景下,JPA的N+1查询问题可通过
@EntityGraph或JOIN FETCH解决。我们已在BookRepository的findWithCategory()方法中演示了预加载分类信息,避免循环查库。”
5.2 “库存扣减怎么保证不超卖?”—— 用代码截图讲清并发控制
准备好IDEA截图:
- 左侧是OrderService.submitOrder()方法,红框标出updateStockForUpdate()调用;
- 右侧是BookRepository的自定义方法,红框标出@Modifying @Query("UPDATE book SET stock = stock - :quantity WHERE id = :bookId AND stock >= :quantity");
- 底部终端截图显示并发压测结果:用ab -n 100 -c 20 http://localhost:8080/api/order/submit,100次请求中98次成功,2次返回“库存不足”,证明机制有效。
强调:“这不是理论,是实测数据。我们用Apache Bench模拟20人同时下单,系统自动拒绝了超卖请求。”
5.3 “管理员和卖家权限怎么隔离的?”—— 画一张动态SQL生成流程图
虽然禁用Mermaid,但可以用文字描述流程:
1. 用户登录后,LoginInterceptor将role存入HttpSession;
2. 卖家访问/seller/book/list时,Controller接收BookQuery对象(含sellerId=当前用户ID);
3. Service层调用bookRepository.findBooksByCondition(query);
4. Repository内部判断:若query.getSellerId() != null,则拼接AND seller_id = ?;否则不拼;
5. 最终执行的SQL自动适配角色视角。
注意:答辩时带一份
BookQuery.java源码打印稿,指着private Long sellerId;字段说:“这就是数据隔离的开关,一行代码,两种世界。”
5.4 “这个系统还能怎么扩展?”—— 给出三个有落地性的升级方向
别只说“加支付”“加物流”,要具体:
-接入微信支付:在OrderService.submitOrder()里,调用微信统一下单API(https://api.mch.weixin.qq.com/pay/unifiedorder),将返回的prepay_id传给前端调起JSAPI支付。关键点是签名算法要用WXPayUtil.generateSignature(params, apiKey),apiKey从sys_config表读取;
-增加商品评价:新建review表(book_id,user_id,content,score,create_time),在BookController加/api/book/review接口,用@Valid校验score必须在1-5之间;
-后台导出订单Excel:用Apache POI,在OrderController加/admin/order/export接口,遍历orderMasterList,每行写入orderNo,userName,totalAmount,statusText,最后用response.getOutputStream().write(workbook.getBytes())输出。
这些扩展点都在现有架构内,无需重构,学生一周内可完成。
6. 避坑指南与独家调试技巧:那些文档里不会写的实战经验
6.1 MySQL中文乱码终极解决方案(亲测100%有效)
即使application.yml写了useSSL=false&serverTimezone=Asia/Shanghai,仍可能乱码。根本原因是MySQL服务端字符集没设对。执行以下三步:
1. 查看当前设置:SHOW VARIABLES LIKE 'character_set_%'; SHOW VARIABLES LIKE 'collation_%';
2. 修改MySQL配置文件(my.ini或my.cnf),在[mysqld]节点下添加:
character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci- 重启MySQL服务:
net stop mysql && net start mysql(Windows)或sudo systemctl restart mysqld(Linux)。
提示:改完后,用
SELECT CHARSET('你好');返回utf8mb4才算成功。很多学生跳过第1步直接改配置,结果发现配置文件路径不对,白忙活。
6.2 IDEA调试时断点不生效?检查Lombok插件三件事
本包大量使用@Data,@Builder,若断点失效,90%是Lombok问题:
-插件未安装:Settings → Plugins → Marketplace搜Lombok,安装并重启;
-注解处理器未启用:Settings → Build → Compiler → Annotation Processors,勾选Enable annotation processing;
-Lombok版本不匹配:pom.xml里lombok版本是1.18.20,则IDEA插件也必须是1.18.20,高版本插件不兼容低版本jar。
实操心得:在
Book.java类上按Ctrl+Q(Quick Doc),若能看到自动生成的getAuthor(),setAuthor()方法文档,说明Lombok工作正常。
6.3 “页面404但控制台没报错”—— Thymeleaf模板路径的隐形规则
Thymeleaf默认从src/main/resources/templates找HTML,但学生常犯两个错:
- 把HTML放在src/main/webapp/WEB-INF/views/下(这是老式SpringMVC路径);
- 文件名用了大写字母(如BookList.html),但Controller里写return "booklist";(Thymeleaf严格区分大小写)。
解决方案:
1. 确认所有HTML都在templates目录;
2. Controller返回值必须与文件名完全一致(return "book-list";对应book-list.html);
3. 在application.yml里加spring.thymeleaf.cache: false,开发时禁用模板缓存,改完HTML不用重启。
6.4 毕设查重规避技巧:代码层面的原创性强化
知网查重不仅查论文,也查代码相似度。本包已做基础规避,你可再强化:
-修改包名:将com.example.bookshop改成com.yourname.graduation,全项目搜索替换;
-重命名实体类字段:Book类的bookName改为titleZh,bookPrice改为salePrice,保持语义不变;
-调整SQL脚本注释:在springbootq3ulr.sql每个建表语句前,加一行-- 作者:张三,2024年6月毕设定制版。
注意:不要改核心逻辑(如库存扣减算法),否则答辩时讲不清。改的是“皮肤”,不是“骨骼”。
7. 项目交付与答辩准备清单:让导师一眼看出你的工作量
7.1 毕设报告撰写要点:用代码截图代替文字描述
导师最烦“本文实现了用户登录功能”这种空话。改成:
-章节标题:“3.2.1 基于JWT的无状态登录实现”;
-正文:“如图3-5所示,LoginController.login()方法接收LoginDTO,调用UserService.checkPassword()验证后,使用Jwts.builder()生成Token,其中subject存用户ID,expiration设为24小时,并签名(密钥从sys_config读取)。前端将Token存localStorage,后续请求在Header加Authorization: Bearer xxx。”
-配图:截取LoginController.java和application.yml中JWT配置段。
这样写,导师知道你真懂JWT,不是抄的。
7.2 演示视频录制建议:聚焦“不可替代性”操作
别录“点点点”的流水账。聚焦三个镜头:
1.第一镜(30秒):对比展示——左边是原始包的BookService.java,右边是你修改后的版本,红框标出你新加的calculateDiscount()方法(比如满100减10),证明你做了业务增强;
2.第二镜(45秒):终端操作——用curl -X POST http://localhost:8080/api/order/submit -H "Authorization: Bearer xxx"模拟API调用,展示Postman返回{"code":200,"msg":"下单成功"},证明你理解前后端分离;
3.第三镜(25秒):数据库验证——Navicat里打开order_master表,指着新插入的记录说:“status字段值为WAIT_PAY,create_time是当前时间,证明订单状态机准确触发。”
7.3 答辩PPT结构:用“问题-方案-证据”黄金三角
一页PPT只讲一件事,遵循:
-左上角:一个真实问题(如“传统Session购物车在多设备登录时丢失”);
-中间:你的方案(“改用数据库存储购物车,cart_item表关联user_id”);
-右下角:证据(截图:CartService.save()方法 + Navicat里查cart_item表的数据)。
最后一页PPT,放一张你部署成功的首页截图,右下角小字:“部署环境:Windows 10 + JDK 8u291 + MySQL 5.7.36 + IDEA 2021.3”。这比任何文字都证明你真的跑通了。
这个图书电商系统,不是让你交差的“填充物”,而是你Java工程能力的实体化证明。从数据库建模时思考范式,到写UPDATE ... WHERE stock >= ?时理解并发,再到改application.yml时明白配置中心的意义——每一个看似微小的操作,都在夯实你作为开发者的底层肌肉。我见过太多学生把毕设当任务,交完就删项目;而真正厉害的人,会把这个包当成种子,在上面长出自己的第一个创业小项目。现在,关掉这篇指南,打开IDEA,敲下mvn spring-boot:run。当你看到那个朴素的图书首页在浏览器里加载出来时,记住:那不只是HTML,那是你亲手点亮的第一盏属于程序员的灯。
本文还有配套的精品资源,点击获取
简介:直接上手就能跑的图书电商平台,用SpringBoot写的纯Java后端,搭配MySQL数据库,B/S架构,前后端分离设计。前台功能包括首页展示、图书搜索、新闻资讯、用户注册登录、购物车增删改查、订单提交与查看;后台分管理员和卖家两个角色——管理员管用户、卖家、分类、商品、全部订单和系统设置;卖家只管自己上架的书、库存更新和对应订单处理。压缩包里有全部可运行源码(含标准src结构)、建库建表SQL脚本(springbootq3ulr.sql)、Word版开发文档、readme启动说明、Maven配置文件(pom.xml、mvnw等)以及2022年录制的操作演示视频。本地部署只需JDK8+、MySQL5.7+、IDEA或Eclipse,按文档步骤导入项目、执行SQL、启动服务即可访问。所有模块已调试通过,适合计算机专业学生做毕业设计、Java课程设计或期末大作业,不需额外改造就能交稿。
本文还有配套的精品资源,点击获取