微信小程序购物商城实战:Java后端+数据库+源码部署与联调指南
简介这是一套面向计算机专业学生与Java后端开发初学者的微信小程序购物商城完整项目适合用作课程设计、毕业设计或技能实训参考。项目采用微信小程序前端搭配Java后端实现商品分类与关键字检索、购物车增减数量、订单提交与收货地址管理以及管理员在Web端处理待发货订单、填写物流信息、管理商品与图片、回复用户评价、维护用户地址等完整业务闭环。压缩包共1539个文件约10.27MB涵盖176个Java源文件、305个JavaScript脚本、385个HTML页面、219张PNG与185张GIF素材以及WXSS、WXML、XML、SQL、JSON等配置与样式文件前后端与数据库脚本齐备。已有205人学习关注。源码均经本地编译可运行评审分达95分以上难度适中且经助教审定配套文档说明与数据库文件便于读者快速理解项目结构、梳理接口逻辑并二次开发。1. 从一份「微信小程序购物商城」压缩包说起它到底能跑出什么很多人第一次拿到「微信小程序购物商城app设计带Java后端源代码文档说明数据库」这类压缩包第一反应是解压、找 README、双击运行然后卡在数据库连不上、后端 404、小程序请求超时这三件事上。这个标题背后其实是一套完整的前后端分离项目实战微信小程序负责用户端展示与交互Java 后端提供 REST 接口MySQL 数据库存商品、订单、用户文档说明负责把部署链路讲清楚。它适合三类人想拿一个完整项目练手的在校生、需要快速搭出商城原型的独立开发者、以及准备 Java 后端面试、想用真实项目讲清楚「接口怎么设计、数据库怎么建」的求职者。核心价值不在代码本身而在于你能把它跑通、改懂、再讲明白。2. 拆开压缩包先看什么目录结构、技术栈与运行前提2.1 一个典型商城项目的目录长什么样拿到压缩包后不要急着导入 IDE先按「前端 / 后端 / 数据库 / 文档」四块把目录认全。常见结构如下不同作者命名略有差异但职责划分基本一致mall-project/ ├── miniprogram/ # 微信小程序前端 │ ├── pages/ # 页面首页、分类、购物车、订单、我的 │ ├── components/ # 自定义组件商品卡片、数量选择器 │ ├── utils/ # request 封装、token 管理 │ └── app.json # 全局配置页面路径、tabBar ├── server/ # Java 后端 │ ├── src/main/java/ # controller / service / mapper / entity │ ├── src/main/resources/ │ │ ├── application.yml │ │ └── mapper/ # MyBatis XML │ └── pom.xml ├── sql/ # 数据库脚本 │ └── mall.sql └── docs/ # 文档说明 └── 部署说明.md认目录的目的是判断这套代码用的是哪种后端组织方式。看到mapper目录和application.yml基本可以确定是 Spring Boot MyBatis 组合看到controller下按UserController、GoodsController、OrderController拆分说明接口是按业务域划分的。这一步花五分钟能省掉后面半小时的瞎找。2.2 技术栈与版本前提先对齐再动手商城类小程序项目的技术栈高度趋同但版本差异是翻车重灾区。下面这张表是我一般会先核对的内容层次常见选型需要确认的点小程序端原生小程序 / uni-app是否用了 uni-app 打包影响编译方式后端框架Spring Boot 2.xJDK 版本是 8 还是 11/17持久层MyBatis / MyBatis-PlusXML 映射还是注解数据库MySQL 5.7 / 8.0驱动版本与连接串参数构建工具Maven本地仓库是否已缓存依赖鉴权JWT / Sessiontoken 放在 header 还是 query提示JDK 版本和 MySQL 驱动版本是最容易导致「本地能跑、换台机器就崩」的两处动手前先确认不要等报错再回头查。2.3 运行前提清单三件事没做就别启动第一本地要有可用的 MySQL 实例并且知道 root 密码或已建好专用账号第二JDK 与 Maven 要能在命令行直接调用java -version和mvn -v都能出结果第三微信开发者工具要装好并且有一个可用的 AppID测试号也行。这三件事缺一件后面必然卡住。我一般会先跑一遍java -version、mysql --version、mvn -v三条命令都通过再往下走避免在环境问题上反复横跳。3. 把数据库和后端跑起来建库、改配置、验接口3.1 导入 mall.sql 并核对表结构数据库是整条链路的底座先把它落地。常见做法是命令行导入避免图形工具编码问题# 登录 MySQL按实际账号替换 mysql -u root -p # 创建数据库并指定字符集商城项目必须用 utf8mb4 才能存 emoji CREATE DATABASE mall DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 退出后用 source 导入脚本 USE mall; SOURCE /path/to/sql/mall.sql;导入完成后一定要核对核心表是否齐全-- 查看所有表 SHOW TABLES; -- 核对商品表结构重点看价格字段类型 DESC goods; -- 确认有初始数据否则小程序首页会是空白 SELECT COUNT(*) FROM goods;逻辑说明utf8mb4是必须的商品名或用户昵称里带 emoji 时utf8会直接写入失败。goods表的价格字段常见是decimal(10,2)如果你看到float下单金额可能出现精度误差这是后面订单对不上账的根源之一。参数上decimal(10,2)表示总共 10 位、小数 2 位足够覆盖绝大多数商城场景。3.2 改 application.yml四个必调参数后端启动前配置文件里的数据库连接是第一个要改的地方spring: datasource: url: jdbc:mysql://localhost:3306/mall?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver servlet: multipart: max-file-size: 10MB # 商品图片上传上限 max-request-size: 10MB server: port: 8080 # 小程序请求的端口要对上逻辑说明serverTimezoneAsia/Shanghai不加会在 MySQL 8 上报时区错误useSSLfalse是本地开发的常规做法避免证书告警。driver-class-name用com.mysql.cj.jdbc.Driver对应 MySQL 8 驱动如果是 5.7 且用的是老驱动要换成com.mysql.jdbc.Driver。端口 8080 要记牢小程序端request封装里的 baseUrl 必须和它一致否则就是清一色的请求失败。3.3 启动后端并验证接口是否真的通了配置改完用 Maven 启动# 在 server 目录下执行 mvn clean package -DskipTests # 运行打好的 jar java -jar target/server-0.0.1-SNAPSHOT.jar看到Started Application in x seconds才算启动成功。接着不要急着开小程序先用命令行验证接口# 测试商品列表接口确认返回 JSON 而不是 404 或 500 curl http://localhost:8080/goods/list?page1size10 # 测试登录接口确认能拿到 token curl -X POST http://localhost:8080/user/login \ -H Content-Type: application/json \ -d {username:test,password:123456}逻辑说明先验接口再连前端能把问题范围缩小到「后端」或「前端」一侧。如果curl返回 404检查 controller 的RequestMapping路径和端口如果返回 500看控制台堆栈多半是数据库连接或 SQL 映射问题。这一步是排查效率最高的分界线我一般不会跳过。4. 小程序端联调请求封装、页面加载与登录态4.1 封装 request把 baseUrl 和 token 收口到一处小程序端最容易散乱的就是请求代码每个页面各写一遍wx.request改端口时要改十几处。正确做法是统一封装// utils/request.js const BASE_URL http://localhost:8080; function request(options) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL options.url, method: options.method || GET, data: options.data || {}, header: { Content-Type: application/json, // 从本地缓存取 token登录后写入 Authorization: wx.getStorageSync(token) || }, success: (res) { if (res.statusCode 200) { resolve(res.data); } else if (res.statusCode 401) { // token 失效跳回登录页 wx.navigateTo({ url: /pages/login/login }); reject(res); } else { reject(res); } }, fail: reject }); }); } module.exports { request };逻辑说明BASE_URL集中管理换环境只改一行Authorization从缓存读取登录成功后写入退出时清除。401 单独处理是商城项目的刚需因为 token 过期后如果不拦截用户会看到一堆莫名其妙的空白页。参数上header里的字段名要和后端拦截器读取的字段名完全一致这是前后端约定不能各写各的。4.2 页面列表加载更多分页参数与触底逻辑商城首页、分类页、订单页都是列表微信小程序页面列表加载更多是高频需求。核心是维护page、size、hasMore三个状态// pages/goods/list.js Page({ data: { list: [], page: 1, size: 10, hasMore: true, loading: false }, onLoad() { this.loadData(); }, // 触底时触发 onReachBottom() { if (this.data.hasMore !this.data.loading) { this.setData({ page: this.data.page 1 }); this.loadData(); } }, loadData() { this.setData({ loading: true }); request({ url: /goods/list?page${this.data.page}size${this.data.size} }).then(res { const newList res.data.records || []; this.setData({ list: this.data.page 1 ? newList : this.data.list.concat(newList), hasMore: newList.length this.data.size, loading: false }); }).catch(() { this.setData({ loading: false }); }); } });逻辑说明hasMore的判断依据是「本次返回条数是否等于 size」小于 size 说明没有下一页了。loading锁防止触底时重复请求这是列表页最常见的 bug 来源。参数上page从 1 开始还是从 0 开始要和后端约定一致很多项目后端用 MyBatis-Plus 分页时page从 1 开始前端如果从 0 开始就会漏掉第一页。4.3 登录态与购物车token 存哪、什么时候清登录成功后后端返回 token小程序端要把它存进wx.setStorageSync(token, token)。购物车、下单、查看订单这些接口都依赖 token。退出登录时不仅要清 token还要清购物车本地缓存否则换账号登录会看到上一个用户的购物车数据。这里有个血泪经验token 过期时间如果设得太短用户逛到一半就被踢回登录页体验极差设得太长又有安全风险。常见做法是 access token 设 2 小时配合刷新机制但很多教学项目为了简单只设一个长 token你要清楚这是简化不是最佳实践。5. 避坑与排查那些让项目「跑不起来」的典型问题5.1 小程序请求全部失败但浏览器能打开接口现象浏览器访问http://localhost:8080/goods/list正常返回小程序里所有请求都失败。原因微信开发者工具默认校验合法域名localhost不在白名单里。解决在开发者工具「详情 → 本地设置」里勾选「不校验合法域名、web-view、TLS 版本以及 HTTPS 证书」。这只在开发阶段用上线必须配真实域名和 HTTPS。5.2 后端启动报「Unknown database」或「Access denied」现象java -jar启动直接抛异常提示数据库不存在或密码错误。原因application.yml里的库名、账号、密码和本地 MySQL 实际不一致或者mall.sql根本没导入。解决先用mysql -u root -p登录SHOW DATABASES;确认mall存在再核对配置文件。注意密码不要带特殊字符不加引号YAML 里password: 123#abc会被截断要写成password: 123#abc。5.3 商品图片上传后不显示现象后台上传图片成功小程序端图片裂开。原因后端把图片存到了本地磁盘但返回给前端的 URL 是相对路径小程序无法解析。解决确认后端有静态资源映射如WebMvcConfigurer里配置/images/**指向磁盘目录并且返回给前端的是完整可访问 URL。另外小程序image的src不支持http之外的协议本地调试时同样受域名校验影响。5.4 下单接口重复提交生成两笔订单现象用户快速点两次「提交订单」数据库里出现两条相同订单。原因前端没有防重复点击后端没有幂等校验。解决前端在请求发出后立即置submitting true并禁用按钮请求结束再恢复后端用订单号唯一索引兜底或者用 token 机制保证同一请求只处理一次。这是前后端对于按钮重复提交校验方法的典型场景两边都要做只做一边都不保险。5.5 数据库中文乱码现象商品名在数据库里显示为问号或乱码。原因建库时没指定utf8mb4或者连接串里characterEncoding写成了utf8而数据里有 emoji。解决建库语句加DEFAULT CHARACTER SET utf8mb4连接串用characterEncodingutf8MySQL 驱动会自动映射到 utf8mb4并确认表和字段的字符集也是utf8mb4。6. 从「能跑」到「能讲」二次开发与面试表达的具体技巧把项目跑通只是起点真正拉开差距的是你能不能改它、讲它。我一般会做三件事。第一加一个真实业务字段比如给goods表加sales销量字段从 entity 到 mapper 到 controller 到小程序展示完整走一遍这一步能让你彻底理解前后端数据流。第二把某个接口从「返回全部字段」改成「按需返回」体会 DTO 和 VO 的区别这是 Java 后端面试的高频考点。第三给订单模块加一个状态机用枚举管理「待付款 / 已付款 / 已发货 / 已完成 / 已取消」面试时讲清楚状态流转和非法流转拦截比背八股有说服力得多。验证改动是否正确的习惯也很重要。我一般会写一个简单的接口测试脚本每次改完跑一遍# 快速回归登录 - 拿 token - 查商品 - 下单 TOKEN$(curl -s -X POST http://localhost:8080/user/login \ -H Content-Type: application/json \ -d {username:test,password:123456} | grep -o token:[^]* | cut -d -f4) curl -s http://localhost:8080/goods/list?page1size5 -H Authorization: $TOKEN逻辑说明把关键链路串成一条命令改完代码跑一次比手动点小程序快得多。参数上grep -o提取 token 依赖返回 JSON 的字段名如果后端字段叫accessToken这里要同步改。还有一个容易被忽略的点源代码管理。拿到项目后第一件事应该是git init并提交一次初始版本之后每改一个功能提交一次。这样改崩了能回滚面试时也能展示你的提交记录比空口说「我做过」有说服力。数据库脚本也要纳入版本管理mall.sql的每次结构变更都单独提交避免「本地能跑、别人拉下来建不了库」。最后说个我自己的教训早期我拿到这类项目总想一口气把所有功能都改一遍结果改到一半自己都记不清哪些是原生的、哪些是我加的出了问题根本定位不到。后来我养成习惯每改一个模块就先跑通、提交、再动下一个宁可慢一点。这个项目值不值得做取决于你是想「收藏一份代码」还是「真正吃透一条前后端链路」——前者解压即止后者值得你花一周把每个接口都亲手调一遍。希望帮到你。本文还有配套的精品资源点击获取