ARTICLE DETAIL

资讯详情

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

基于Java+SSM的果蔬农产品商城开发与部署实战

基于Java+SSM的果蔬农产品商城开发与部署实战 简介基于Java和SSM框架的水果蔬菜农产品购物商城项目是一套面向高校计算机相关专业毕业生的毕设与课设参考源码。项目使用Spring、SpringMVC、MyBatis经典组合实现了前台农产品展示、购物车、订单处理以及后台管理等核心功能既能用于毕业设计答辩也可作为课程作业或SSM入门后的进阶练习。资源包内共1575个文件大小约20.4MB包含Java源文件、JSP页面、SQL数据库脚本、MyBatis映射文件以及大量CSS、JavaScript、图片等前端素材另有使用文档与配置文件结构清楚导入开发环境后即可运行查看目前已有166人学习下载。源码经过实际环境测试在Windows10/11和macOS下均可正常运行并获导师指导认可答辩评审分达到95分。配套的数据库脚本和说明文档能帮助使用者快速搭建运行环境、理解业务实现也可在此基础之上继续扩展直接用于毕业设计、课程设计或项目初期演示。1. 基于 JavaSSM 的果蔬农产品商城先看它值不值得你花时间复现别急着解压那个写着“高分优秀项目”的压缩包。一个基于 JavaSSM 的果蔬农产品购物商城真正卡住你的往往不是源码本身而是环境JDK 版本、Maven 依赖、MySQL 驱动、Tomcat 部署方式任何一项没对上项目都会在启动阶段直接翻车。这类项目本质上是一套典型的三层结构电商系统前台让用户注册、浏览水果蔬菜、加购物车、生成订单后台管理商品和订单。它适合两类人一是要交毕业设计并准备答辩的在校生二是想快速搞懂 Spring、SpringMVC、MyBatis 如何配合、把数据库增删改查真正落到页面上的 Java 学习者。我下面按“项目是什么—怎么跑起来—核心模块—排错—验收”的顺序讲照着做两天内你能得到一套能演示、能讲设计、能应付追问的系统。2. 系统架构与数据库设计SSM 下商城模块怎么切、数据表怎么落到 MySQL先记住一个选择框架SSM 是 Spring、SpringMVC、MyBatis 的组合不是三个必须分开学的东西。Spring 管对象SpringMVC 管 HTTP 请求到方法的映射MyBatis 管 SQL 与 Java 实体之间的转换。相比 Spring Boot 全家桶SSM 的配置是显式的数据源在哪里、拦截器在哪里、SQL 写在哪里打开 XML 一清二楚。这恰恰是毕业设计里容易拿分的地方——答辩老师问“事务配置在哪、为什么这样配”时你能指给他看而不是只说“框架自动处理了”。2.1 一个“高分会答辩”的模块切分前台商城与后台管理果蔬农产品商城和普通百货商城最大的差别是商品形态水果论“斤”卖蔬菜按“份”卖活动价天天波动库存要实时准。所以在模块切分上我会把系统分成两个 Web 入口分别对应前台商城和后台管理它们共用同一套 Service 和 Mapper只是 Controller 层分开。前台商城包含首页分类导航、推荐商品、搜索框、商品列表页按分类筛选、按销量或价格排序、商品详情页价格、单位、库存、销量、购物车、结算页收货地址、订单金额、我的订单。后台管理包含管理员登录、商品管理上架、下架、改价、改库存、传图、分类管理、订单管理查看、发货、关闭订单、用户管理禁用、启用。前后台放在同一个 Tomcat 里后台 URL 统一加/admin前缀再通过拦截器做权限控制。这样拆分的好处是答辩时很直观模块图画出来就是两个大框每个大框两三行字能讲完。很多高分项目的核心结构都是这个套路你的重点不是发明新框架而是把每个模块怎么实现说清楚尤其是下单、库存、订单状态这三个地方。2.2 数据库表设计与字段约束用户、商品、订单、地址之间怎么关联数据库是整个项目里最先要定死的东西。表没设计好后面所有 SQL 都要返工。一个典型 SSM 果蔬商城的核心表我列在下面表名核心字段作用userid, username, password, nickname, phone, create_time前台注册用户categoryid, name, parent_id商品分类果/蔬/肉蛋/粮油productid, name, category_id, price, stock, unit, image, status, sales果蔬商品cartid, user_id, product_id, quantity购物车记录addressid, user_id, receiver_name, receiver_phone, detail, is_default收货地址ordersid, order_no, user_id, address_id, total_amount, status, pay_type主订单order_itemid, order_id, product_id, product_name, price, quantity, subtotal订单明细注意一个细节MySQL 里的order是保留关键字所以订单表建议叫orders或t_order否则写 SQL 时一直要加反引号非常烦。果蔬类商品的stock字段我建议用DECIMAL(10,2)而不是 INT。因为一斤、半斤这种重量积压很常见INT 只能按整数卖但如果你项目里的商品都是盒装、袋装用 INT 也够。关键是文档里要写明你选了哪种答辩时老师问“为什么库存用小数”你能自圆其说。开发中期你大概率会遇到“加字段”的需求。比如想给商品加一个首页推荐标记直接在数据库里执行ALTER TABLE product ADD COLUMN is_recommended TINYINT DEFAULT 0 COMMENT 1表示首页推荐;改表之后同步改三处实体类 Product.java 加属性Mapper 的 resultType 或 resultMap 匹配新字段后台商品新增/修改表单加对应项。如果项目是手动管理 SQL 文件记得把这条 ALTER 语句也补进建表脚本否则换机器重新部署时新库表结构和你的实体类对不上启动起来又是一堆字段不存在的报错。2.3 数据访问层落到 MyBatisMapper 接口、XML 与增删改查MyBatis 的访问层通常由三部分组成Mapper 接口、Mapper XML、实体类。接口定义方法XML 写 SQL实体类做字段映射。以商品列表多条件查询为例常见做法是这样的mapper namespacecom.farm.mapper.ProductMapper select idselectPage resultTypecom.farm.entity.Product SELECT id, name, category_id AS categoryId, price, stock, unit, image, sales FROM product where if testkeyword ! null and keyword ! AND name LIKE CONCAT(%, #{keyword}, %) /if if testcategoryId ! null AND category_id #{categoryId} /if AND status 1 /where ORDER BY sales DESC /select /mapper这里有两个关键点#{}是预编译占位符会自动处理参数类型并防止 SQL 注入一定不要用字符串拼接的方式写条件where和if是 MyBatis 动态 SQL有参数才拼条件没有就跳过可以少写好几段分支判断。对应的 Mapper 接口是这样public interface ProductMapper { ListProduct selectPage(ProductQuery query); Product selectById(Param(id) Integer id); int insert(Product product); int update(Product product); int deleteById(Param(id) Integer id); }这套就是“数据库增删改查”在 SSM 项目里的落地点。插入返回受影响行数更新同样返回行数删除建议做逻辑删除而不是物理删除把status改成 0这样商品只是下架历史订单里还能查到商品名和价格。物理删除一旦误删订单明细里就只剩一个空引用演示时会很难看。分页是商城列表绕不开的需求。项目里通常会引入 PageHelper 插件在 Service 层调用PageHelper.startPage(pageNum, pageSize)之后紧跟的第一条 SQL 会自动拼上 LIMIT。要注意 PageHelper 的生效范围是“下一条查询”所以 startPage 和 mapper 查询之间不要插入其他无关的 SQL 操作否则分页会生效在错误的语句上查出来的数据数量完全不对。3. 把压缩包里的项目跑起来环境准备、SQL 导入与 Tomcat 部署这一章解决的是“拿到压缩包后第一步做什么”。很多毕业设计项目本身的代码没问题最后挂掉是因为跑起来的方式不对有人直接双击 JSP有人用 IDEA 打开后随手选了错误的 JDK有人导入 SQL 时报了一堆错就放弃。其实只要按固定顺序处理二十分钟内能启动。3.1 先从使用文档和目录结构确认环境要求解压之后先别急着往 IDE 里拖。先用资源管理器看一遍顶层结构重点找 README 或者“使用文档.doc/x.md”。这类毕业设计压缩包里的使用文档一般会写明JDK 版本、Tomcat 版本、MySQL 版本、数据库账号密码、部署方式。这不是摆设而是一个项目唯一可信的环境声明。如果文档和你的本机环境有出入以文档为准然后在心里记下“这里可能需要改”。常见目录结构大概是这样farm_market/ ├─ pom.xml ├─ sql/ │ └─ farm_market.sql ├─ src/main/java ├─ src/main/resources │ ├─ jdbc.properties │ ├─ applicationContext.xml │ ├─ springmvc-config.xml │ └─ mybatis-config.xml ├─ src/main/webapp │ ├─ WEB-INF/web.xml │ ├─ static/ │ └─ jsp/ └─ 使用文档.md看到pom.xml说明这是 Maven 项目Maven 会自动拉依赖看到webapp说明项目用 JSP 做页面看到sql目录说明数据库脚本独立。我一般会顺手确认三件事pom.xml 里 Spring 版本是不是 4.x/5.x连接 MySQL 的驱动 jar 是 5.x 还是 8.xweb.xml 里 DispatcherServlet 的url-pattern是不是/。这三个信息决定了后面配置怎么改。3.2 初始化数据库建库、导 SQL、验证种子数据数据库导入是整个部署过程中最机械、也最容易出错的一步。先把 MySQL 服务确认起来然后命令行登录mysql -uroot -p CREATE DATABASE IF NOT EXISTS farm_market DEFAULT CHARACTER SET utf8mb4; USE farm_market; SOURCE /path/to/farm_market.sql;SOURCE后面的路径要写 SQL 文件的绝对路径Windows 下路径里的反斜杠记得改成单斜杠或者直接用source命令时把路径用正斜杠写。如果你用 Navicat 或 MySQL Workbench也可以直接“运行 SQL 文件”效果一样。导入之后别急着走做两步验证SHOW TABLES; SELECT id, name, price, status FROM product LIMIT 5;SHOW TABLES能确认所有表是否建好查 product 的前五行能确认初始数据是否真的写进去了。常见问题是 SQL 脚本本身包含CREATE DATABASE语句如果你在 Navicat 里已经选了某个库再执行可能冲突这时删掉脚本头部的建库语句只保留建表和插入即可。还要记住文档里写的初始账号比如admin/123456它很可能就在 SQL 的 INSERT 语句里找不到就从 admin 表里直接查。3.3 数据库连接配置jdbc.properties 的每一项都可能让你翻车SSM 项目的数据库连接配置通常在src/main/resources/jdbc.properties内容长这样jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/farm_market?characterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue jdbc.usernameroot jdbc.password你的数据库密码这里的参数每个都有讲究。com.mysql.cj.jdbc.Driver是 MySQL 8 的驱动类如果项目用的驱动是旧版 5.1.x就要改成com.mysql.jdbc.Driver。serverTimezoneAsia/Shanghai是 MySQL 8 常见的时区参数不加可能在连接时报The server time zone value ... is unrecognized。allowPublicKeyRetrievaltrue是解决 MySQL 8 默认加密插件连接问题的一个开关很多项目就是少它连不上。改完配置之后最好去applicationContext.xml里确认一下 properties 文件有没有被正确加载context:property-placeholder locationclasspath:jdbc.properties/如果项目里同时存在多个 properties 配置文件比如db.properties和redis.properties要注意 location 是否写全。我自己踩过坑配置写对了但 Spring 加载的是另一个同名文件数据库密码怎么改都不对。遇到这种问题直接在配置类或 XML 里搜jdbc.password看它引用的到底是哪个文件。3.4 启动服务IDEA 部署 Tomcat 与直接打 war 包两种方式跑 SSM 项目最常见的方式是用 IDEA 配置本地 Tomcat。具体步骤是用 IDEA 以 Maven 项目方式打开解压后的根目录等依赖下载完成然后打开 Run/Debug Configurations添加 Tomcat Server 的 Local 配置在 Deployment 里加入war exploded格式的 artifactApplication context 填/farm_market注意要和使用文档中的访问路径一致最后选好 JDK 和端口启动。如果你更习惯命令行方式也可以先把项目打成 war 包再丢给 Tomcatmvn clean package cp target/farm_market.war ${TOMCAT_HOME}/webapps/ ${TOMCAT_HOME}/bin/startup.sh启动成功后访问http://localhost:8080/farm_market/。如果依赖下载很慢八成是没配国内 Maven 镜像。在 Maven 的settings.xml里加一个 mirror 是最常见的解决方案mirror idaliyun/id mirrorOfcentral/mirrorOf urlhttps://maven.aliyun.com/repository/public/url /mirror这一步不是项目问题而是环境问题但九成新手都卡在依赖下载半路失败上。配置好镜像之后用mvn -U clean compile强制刷新一次让缺失的 jar 重新拉取。4. 核心业务实现注册登录、商品分页、购物车与订单事务系统跑起来之后真正的难点回到代码。SSM 商城项目里最有含金量、也最常被答辩追问的是四个点登录会话、商品分页检索、下单事务、后台权限。把这几段吃透整个项目就讲得出东西了。4.1 SSM 常用注解把三层串起来从 Controller 到 Mapper先看登录这个场景如何用“SSM 常用注解”串起来。前台用户提交用户名密码时Controller 接收参数调用 Service 去 Mapper 里查库Controller RequestMapping(/user) public class UserController { Autowired private UserService userService; RequestMapping(value /login, method RequestMethod.POST) public String login(String username, String password, HttpSession session, HttpServletRequest req) { User user userService.login(username, password); if (user ! null) { session.setAttribute(user, user); return redirect:/product/list; } req.setAttribute(error, 用户名或密码错误); return login; } }这段代码里的Controller告诉 Spring 这是一个表现层组件RequestMapping把 URL 映射到方法Autowired把 UserService 注入进来HttpSession由 SpringMVC 自动从 request 中解析。这三行注解就是面试题里常被问的“SSM 如何工作”的标准答案。Service 层同样用注解标记为 Spring 管理的 BeanMapper 接口则由 MyBatis 帮我们生成代理实现。要注意登录查询 Mapper 时密码比对应该在 Java 里做还是在 SQL 里做。常见做法是先用账号查出完整用户对象再用 Java 比对密码哈希这样可以区分“账号不存在”和“密码错误”符合正常逻辑答辩时也更好讲。4.2 商品列表与多条件检索分页插件、LIKE 查询与排序商品列表页是商城流量最大的页面通常需要支持按分类筛选、按关键字模糊搜索、按销量/价格/上架时间排序。这些条件不能每个都写一个 mapper 方法正确做法是用 MyBatis 动态 SQL 拼一条通用查询。上一章的selectPage已经展示了核心写法这里看 Service 层怎么配合Service public class ProductServiceImpl implements ProductService { Autowired private ProductMapper productMapper; Override public PageInfoProduct page(Integer pageNum, Integer pageSize, String keyword, Integer categoryId) { ProductQuery query new ProductQuery(); query.setKeyword(keyword); query.setCategoryId(categoryId); PageHelper.startPage(pageNum, pageSize); ListProduct list productMapper.selectPage(query); return new PageInfo(list); } }PageHelper.startPage之后必须紧跟productMapper.selectPage(query)这一条查询PageHelper 会生成 count 查询和分页 SQL。PageInfo里封装了当前页数据、总记录数、总页数、是否有下一页等信息JSP 里可以用它对 list 做分页渲染。排序同样要交给数据库完成而不是取出全部数据到 Java 里排序。商品总量可能上万条全部拉到 JVM 内存里用 Collections.sort 或 Stream 排序性能会很难看。“java排序”相关的问题在面试里经常被问可以顺势说清楚内存排序适合购物车这种小规模数据数据库 ORDER BY 才适合商品列表这种可能无限增长的数据。4.3 加入购物车、下单与库存扣减事务和状态机下单是商城系统里最核心的一段事务逻辑也是答辩老师最喜欢追问的地方。一个订单的生成涉及多张表插入订单主表、插入订单明细表、扣减商品库存、增加商品销量、清空购物车。任何一个环节失败都不允许留下半截脏数据所以必须在 Service 方法上加事务注解。Service public class OrderServiceImpl implements OrderService { Autowired private OrderMapper orderMapper; Autowired private OrderItemMapper orderItemMapper; Autowired private ProductMapper productMapper; Transactional(rollbackFor Exception.class) public String createOrder(Order order, ListCartItem cartItems) { order.setOrderNo(String.valueOf(System.currentTimeMillis()) new Random().nextInt(1000)); order.setStatus(0); orderMapper.insert(order); for (CartItem item : cartItems) { OrderItem oi new OrderItem(); oi.setOrderId(order.getId()); oi.setProductId(item.getProductId()); oi.setPrice(item.getPrice()); oi.setQuantity(item.getQuantity()); oi.setSubtotal(item.getPrice().multiply(item.getQuantity())); orderItemMapper.insert(oi); productMapper.decreaseStock(item.getProductId(), item.getQuantity()); productMapper.increaseSales(item.getProductId(), item.getQuantity()); } return order.getOrderNo(); } }注意Transactional的rollbackFor必须写成Exception.class否则 Spring 默认只在遇到 RuntimeException 时回滚选中受检异常时下单会半成功。金额字段如果是 BigDecimal计算小计一定用multiply而不是*这是 Java 基础里最容易出错的精度点。库存扣减最好用一条带条件的 UPDATEupdate iddecreaseStock UPDATE product SET stock stock - #{quantity} WHERE id #{productId} AND stock #{quantity} /update这条 SQL 的巧妙之处是“库存不够时更新影响行数为 0”。Mapper 方法返回 int代码里判断if (productMapper.decreaseStock(...) 0) throw new RuntimeException(库存不足)事务就会整体回滚并且不会出现超卖库存负数。这种写法就比“先 SELECT 库存再 UPDATE”安全得多因为两条语句之间的并发缺口被锁住了。答辩时把这里讲清楚是一个明显高于普通毕业设计的亮点。4.4 后台商品管理与权限控制角色级判断与行级扩展后台管理模块的本质是“商品增删改查 订单状态流转”对应的 Mapper 方法就是 insert、update、delete、select没有太复杂的技术。需要注意的其实是权限控制。很多项目把后台管理页面直接丢出来未登录也没拦住这在答辩时会被扣分。常规做法是加一个 SpringMVC 拦截器只放行登录页和登录请求public class AdminInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { Object admin request.getSession().getAttribute(admin); if (admin null) { response.sendRedirect(request.getContextPath() /admin/login); return false; } return true; } }拦截器在 springmvc-config.xml 里注册mvc:interceptors mvc:interceptor mvc:mapping path/admin/**/ mvc:exclude-mapping path/admin/login/ bean classcom.farm.interceptor.AdminInterceptor/ /mvc:interceptor /mvc:interceptors这段配置足够覆盖角色级权限普通用户进不了/admin/**管理员登录后才能在后台操作。如果答辩被追问更深层的“行级权限 java 怎么控制”可以答把操作人和商品归属人关联比如在 product 表加operator_id查询时强制过滤这个条件修改前检查当前管理员是否有权操作该商品。毕业设计项目不用真实现但能说出来就说明你对权限模型有认识。5. 运行排错与避坑从源码到能演示的 5 个常见翻车点我见过不少同学把源码解压后原封不动放进 IDEA一启动先弹十几个报错。说实话这些报错九成以上不是代码问题而是环境、依赖、参数不一致。下面这 5 个坑是按出现频率排的每个都是“现象 → 原因 → 解决”的结构对应照着排查就行。5.1 编译报错“程序包 org.springframework.stereotype 不存在”现象打开项目后Controller 类上Controller注解大面积飘红Maven 编译时报“程序包 org.springframework.stereotype 不存在”。原因Maven 依赖没有正确解析。可能是 pom.xml 损坏可能是本地仓库里对应 jar 下载不完整也可能是 IDEA 没有识别这个 Maven 项目。解决先执行mvn -U clean compile强制刷新依赖然后再回到 IDEA 里右键项目选 Maven 的 Reload Project。如果还不行打开本地 Maven 仓库目录找到 org/springframework 相关文件夹删除让 Maven 重新下载。另外确认 IDEA 的 Project SDK 是 JDK 8而不是高版本 JDK 导致编译级别不一致。5.2 数据库连不上驱动类、时区、公钥检索现象Tomcat 启动后日志里报Cannot create PoolableConnectionFactory或Public Key Retrieval is not allowed。原因MySQL 8 默认使用 caching_sha2_password 认证旧版驱动不认识或者连接串里没带serverTimezone驱动连不上服务器时区信息。解决在 jdbc.properties 里把驱动改成com.mysql.cj.jdbc.Driver连接串加上serverTimezoneAsia/Shanghai和allowPublicKeyRetrievaltrue。如果你用的是 MySQL 5.7驱动类用com.mysql.jdbc.Driver即可。还有一种隐蔽情况项目把 mysql-connector jar 也放进了 Tomcat 的 lib 目录和 webapp 里自带的驱动版本冲突产生ClassNotFoundException或奇怪的方法不存在这时把 Tomcat lib 下多余的 mysql jar 删掉。5.3 页面样式和 JS 全 404静态资源被拦截现象首页能打开但 CSS、JS、图片全部加载失败页面变成纯文字乱排版。原因SpringMVC 的 DispatcherServleturl-pattern配置为/把静态资源请求也当成了 Controller 映射静态文件自然找不到处理者。解决在 springmvc-config.xml 里补上资源放行配置mvc:resources mapping/static/** location/static// mvc:default-servlet-handler/同时检查 JSP 里静态资源引用是否带了上下文路径link relstylesheet href${pageContext.request.contextPath}/static/css/common.css少了pageContext.request.contextPath页面会去根路径找样式路径错了就还是 404。5.4 中文乱码数据库、连接串、JSP 三方不一致现象注册用户姓名显示成“??”或者后台添加的商品名称存进数据库后变成乱码。原因数据库表字符集、JDBC 连接串字符集、JSP 页面字符集这三者不一致。最常见的组合是数据库用的 latin1连接串没有characterEncodingutf8页面又是 UTF-8。解决第一步统一连接串在jdbc.url里加characterEncodingutf8。第二步确认表结构已经是 utf8mb4如果不确定就重建相关表。第三步在 web.xml 中注册 Spring 提供的字符编码过滤器filter filter-nameencoding/filter-name filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param init-param param-nameforceEncoding/param-name param-valuetrue/param-value /init-param /filter这个坑最伤的地方在于改了表结构之后旧数据已经变成乱码只能清掉重新导入 SQL 脚本所以一开始就统一字符集最省事。5.5 Tomcat 端口被占用或启动慢到像卡死现象启动 Tomcat 时报Port 8080 was already in use或者日志半天没动静。原因上一轮项目没有正确关闭Tomcat 进程残留有时是其他程序占用了 8080。解决Windows 下用命令找进程号并强制结束netstat -ano | findstr 8080 taskkill /PID 占用8080的进程号 /FmacOS/Linux 下lsof -i :8080 kill -9 进程号至于启动慢我的经验是先确认 MySQL 是否已启动。如果 MySQL 没起来Druid 连接池初始化会一直重试Tomcat 看起来就像卡住。把 MySQL 先启动好再重启 Tomcat通常十几秒内能完成。6. 用一套验收脚本把功能走查一遍答辩时讲清这三个技术点系统能启动只是第一步。真正让项目“高分”的是你答辩前能把所有功能逐项走通并且用一条主线把技术讲清楚。我建议按下面这套验收脚本过一遍不用写自动化测试手工操作即可边操作边看数据库变化序号走查项操作步骤预期结果01注册登录前台注册新用户并登录首页显示用户名user 表新增记录02商品检索搜索“苹果”再按蔬菜分类进入列表数量和关键字匹配03加入购物车加购 2 份把数量改为 3购物车数量和合计金额正确04提交订单选地址提交查看库存订单生成product 表 stock 减少05后台发货管理员把订单置为待收货前台“我的订单”状态同步变化06权限校验未登录直接访问 /admin跳转到管理员登录页走查的同时去数据库实时刷一下SELECT你会对“请求从页面到数据库”的路径更有画面感。这个习惯在答辩前一天特别有用哪怕紧张到说不出注解名你也能讲清楚数据从哪个表流向哪个表。答辩的技术点建议集中讲三个。第一个是商品列表的分页和排序说清楚 PageHelper 如何拦截下一条 SQL排序为什么放在 MySQL 而不是 JVM这样既解释了 MyBatis 动态 SQL又体现了你对“java排序”实用边界的理解。第二个是下单事务从点击提交按钮开始依次发生了什么事务、哪几张表被写库存扣减为什么要用stock #{quantity}条件。第三个是权限控制你不是在后台页面里藏了个入口而是用拦截器统一拦住/admin/**并放行登录请求。这三个点能讲清楚就已经覆盖了整个项目的大部分技术分。我自己的习惯是项目跑通后立刻在 README 里补一段“运行笔录”把 JDK 版本、MySQL 版本、Tomcat 版本、改过的 jdbc.properties 和本机端口都记下来。别小看这份记录到答辩前一天它比源码更容易让你冷静下来。希望帮到你。本文还有配套的精品资源点击获取
返回列表