ARTICLE DETAIL

资讯详情

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

SSM+微信小程序全栈实战:从架构到联调的完整指南

SSM+微信小程序全栈实战:从架构到联调的完整指南 简介面向Java毕业设计或课程设计学习者基于SSMSpring、SpringMVC、MyBatis与微信小程序的中国剪纸项目覆盖小程序端、后台管理端和数据库设计完整呈现前后端分离开发流程适合快速搭建可演示作品并理解企业级项目结构。压缩包共722个文件大小28.1MB以Java后端源码102个、Vue后台管理页面101个、JS逻辑64个、WXML/WXSS小程序界面43个、SQL数据库脚本为核心并包含PPT、开题报告、任务书、使用文档、演示视频等答辩材料另有SVG图标、PNG/JPG图片、JSON/XML配置、CSS样式和MD说明等资源以及安装/运行/构建批处理脚本便于快速部署。目前已有115人学习下载。项目已通过导师认可与答辩评审获得97分在Windows10/11环境严格调试下载后按配套部署教程即可运行也可直接作为课程设计参考。演示视频和文档覆盖SSM框架整合、小程序API调用、数据库表设计等关键环节同时保留源码备份与样式文件方便二次修改与学习。1. 一套能直接跑起来的 SSM微信小程序项目先分清你要的是源码还是交付链路每年毕业设计季都会有一大批 Java 毕业设计源码包在同学之间流传标题越写越长比如这套「基于 SSM微信小程序的中国剪纸」后面还挂着一串交付物源码、数据库、PPT、开题报告、任务书、使用文档、演示视频。多数人拿到手的第一反应不是打开源码而是「这玩意儿到底怎么跑起来」。其实这套包真正值钱的不是代码量而是它把「从零搭一个 SSM 后端、设计数据库、再对接微信小程序端」这条完整链路提前走了一遍你只需要把它跑通、讲清、答得上。它适合两类人Java 基础一般但需要高质量毕设的本科生以及想快速看一遍 SSM小程序全栈调用关系的入门开发者。2. 先把 SSM 后端跑通架构拆解与最小启动配置2.1 三层架构与包结构MVC 在剪纸项目里怎么落位SSM 不是某个框架的名字是 Spring、SpringMVC、MyBatis 三个框架的合称。在剪纸项目里它们各管一段Spring 管对象把 Service、Mapper 这些 Java 对象交给容器创建和管理你在 Controller 里只管用不用自己 newSpringMVC 管请求小程序发来的 HTTP 请求先到 ControllerController 把参数拆出来调 Service再把结果包成 JSON 返回MyBatis 管数据库Mapper 接口定义方法XML 文件里写 SQL查询结果自动映射成实体对象。这里要先纠正一个常见误解SSM 和 Spring Boot 不是一回事。Spring Boot 是把这些框架内嵌好、自动配置的一整套方案而 SSM 是三个框架手动拼起来这意味着你要面对一堆 XML 配置。还有这个项目是后端渲染 JSON 给小程序用Controller 返回的是数据而不是页面所以包结构一定不能按「返回 JSP」的老思路去理解。com.example.papercut ├── controller # 接收小程序请求返回 JSON ├── service # 业务接口 │ └── impl # 业务实现事务注解放在这里 ├── mapper # MyBatis 接口一个接口对应一张表的增删改查 ├── entity # 实体类与表字段一一对应 ├── common # 统一返回结果、异常处理、工具类 └── config # 拦截器、跨域等配置为什么 Service 要写接口再写实现这是 SSM 的标准套路答辩时也好讲——接口定义行为实现类写具体逻辑将来换实现不用动调用方。很多毕设为了省事只写实现类能跑但老师一问「你 Service 层怎么设计的」就露怯。包结构里还必须有一个 common 包里面放统一的 Result 返回体否则每个接口都各自返回 Map 或裸对象前端处理起来会很痛苦。2.2 最小启动配置pom、SpringMVC 与 MyBatis 三个文件的取舍拿到源码包后不要急着改业务代码先把依赖和配置确认一遍SSM 项目最容易翻车的地方全在配置文件里。先看 pom.xml核心依赖就是下面这几个缺哪个都起不来。dependencies dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId /dependency dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId /dependency /dependencies参数说明版本号以你项目里现有的为准不要擅自升级SSM 这个组合从 Spring 4 到 Spring 5 的写法有差异你自己去升最容易把依赖升出冲突。jackson-databind 是给 ResponseBody 做 JSON 序列化用的缺了它接口会直接报 406 或者返回乱码这个依赖平时最容易被忽略。然后是 web.xmlDispatcherServlet 是请求入口它的 url-pattern 决定了哪些请求进 SpringMVC。SSM 老项目很多配的是*.do如果小程序端请求路径不带.do就会 404新项目配/让 SpringMVC 接管所有请求。我的建议是打开源码先看 web.xml 里怎么配的再去小程序端找对应的请求路径。Spring 和 MyBatis 的配置文件里真正要改的也就三个配置项!-- 扫描 service 和 mappercontroller 由 springmvc.xml 单独扫描 -- context:component-scan base-packagecom.example.papercut.service/ !-- 配置数据源URL 里必须带编码参数否则中文全变问号 -- bean iddataSource classorg.apache.commons.dbcp.BasicDataSource property namedriverClassName valuecom.mysql.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/papercut?characterEncodingutf8/ /bean !-- SqlSessionFactory告诉 MyBatis 去哪里找 mapper 的 XML 文件 -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ property namemapperLocations valueclasspath:mapper/*.xml/ /bean参数说明component-scan 只扫 service不扫 controller这是 SSM 的潜规则两边各扫各的。如果扫描包路径重叠得太多会出现事务失效之类的怪问题。mapperLocations 用classpath:mapper/*.xml意思是所有 Mapper XML 放在 resources/mapper 目录下文件名随意但路径要对上。数据源的 URL 里 characterEncodingutf8 必加这个问题后面避坑章节还会再踩一次。2.3 从登录接口看 Controller-Service-Mapper 的完整调用链配置跑通后找一个最简单的接口——微信登录把三层调用链走一遍。小程序端 wx.login 拿到的临时 code后端拿这个 code 调微信接口换 openid再查本地用户表。很多毕设直接做账号密码登录但也只要一套逻辑Controller 接收请求Service 做校验和注册Mapper 查库。RestController RequestMapping(/api/user) public class UserController { Autowired private UserService userService; /** 微信登录前端传 code后端返回登录用户 */ PostMapping(/login) public Result login(RequestBody LoginRequest req) { User user userService.loginByCode(req.getCode()); if (user null) { return Result.error(登录失败未获取到用户信息); } return Result.ok(user); } }说明RestController 表示这个类里方法的返回值直接写进响应体不用再拼视图RequestBody 把前端传来的 JSON 字符串反序列化成 LoginRequest 对象前提是 jackson 依赖在并且请求头的 Content-Type 是 application/json。很多新手把 RequestBody 加到 GET 请求上结果参数永远取不到这是最常见的低级错误。Service 层做的事通常比 Controller 多一些先查本地表有没有这个 openid没有就自动注册一条新用户有就直接返回这就是「首次打开小程序自动完成注册」的实现思路。Mapper 层只干一件事按 openid 查用户select idselectByOpenid resultTypecom.example.papercut.entity.User SELECT id, openid, nickname, avatar, phone, create_time FROM user WHERE openid #{openid} /select参数说明#{openid}是预编译占位符不是字符串拼接这能挡住大部分 SQL 注入面试时被问到「你怎么防 SQL 注入」就这么答。resultType 写全限定类名时MyBatis 会按「列名转驼峰」自动映射字段但前提是配置文件里开了 mapUnderscoreToCamelCase这个坑后面细说。2.4 SSM 常用注解怎么选五个注解对应五种职责答辩时老师常问「你项目里用了哪些注解」面试也绕不开 SSM 常用注解。在剪纸项目里真正用得上的就是下面这五类我按使用频率排了个表。注解放在哪作用常见误用RestControllerController 类标记请求处理类返回值直接写响应体忘记加导致返回的是视图名而不是 JSONServiceService 实现类标记业务组件交给 Spring 管理写在接口上导致代理失效Autowired字段 / setter依赖注入和 Resource 混用按类型和按名字的逻辑不同TransactionalService 方法上声明事务同类内部调用时事务不生效RequestBody / RequestParamController 参数绑定请求数据两者混用导致参数为 null重点说 Transactional这是最容易翻车的。它的原理是 Spring AOP 生成代理对象事务加在代理上。如果你在同一个类里A 方法调 B 方法B 上有 TransactionalB 的事务不会生效因为调用发生在类内部没走代理这个坑叫「自调用失效」。我见过一个同学订单接口扣库存但事务没生效数据写到一半答辩现场演示直接翻车。解决方式也简单把需要事务的方法拆到另一个 Service 类里或者自己注入自己代理。这个知识点讲出来比背概念有用得多。3. 剪纸业务的数据落点数据库设计与数据流3.1 核心表结构用户、作品、分类、收藏、订单、公告这套项目的业务很简单核心就是「看剪纸、收藏剪纸、买剪纸」。围绕这个业务数据库一般六张表就够user 用户表、category 分类表、paper_cut 剪纸作品表、favorite 收藏表、orders 订单表、notice 公告表。这里给出最关键的两张建表语句其他表照着这个风格扩展就行。-- 用户表小程序端授权登录的用户 CREATE TABLE user ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键, openid VARCHAR(64) NOT NULL COMMENT 微信openid唯一, nickname VARCHAR(50) DEFAULT COMMENT 昵称, avatar VARCHAR(255) DEFAULT COMMENT 头像URL, phone VARCHAR(11) DEFAULT COMMENT 手机号, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间, PRIMARY KEY (id), UNIQUE KEY uk_openid (openid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; -- 剪纸作品表 CREATE TABLE paper_cut ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键, title VARCHAR(100) NOT NULL COMMENT 作品名称, category_id BIGINT NOT NULL COMMENT 分类ID, cover_url VARCHAR(255) DEFAULT COMMENT 封面图URL, detail_images TEXT COMMENT 详情图多个URL用逗号分隔, price DECIMAL(10,2) DEFAULT 0.00 COMMENT 价格, description TEXT COMMENT 作品描述, status TINYINT DEFAULT 1 COMMENT 0下架 1上架, sales INT DEFAULT 0 COMMENT 销量, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 录入时间, PRIMARY KEY (id), KEY idx_category (category_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT剪纸作品表;说明openid 是微信平台的用户唯一标识设成唯一键防止同一用户重复注册。detail_images 用 TEXT 存逗号分隔的多个图片 URL是毕设项目里的常见简化方案生产环境会拆成子表但答辩阶段够用。price 坚持用 DECIMAL 不用 FLOAT因为浮点数计算金额会出现 0.10.2 不等于 0.3 的精度问题这个细节讲出来很加分。3.2 字段类型与索引参数用一张剪纸作品表讲清楚建表时拿不准字段类型我一般按这几个标准判断。字符串作品标题这种短文本用 VARCHAR(100)够用且查询快描述、详情这类长内容用 TEXT。注意 TEXT 不能设默认值如果你给 description 加 DEFAULT 子句MySQL 直接报错这是硬限制经常有人在这翻车。金额一律 DECIMAL(10,2)整数部分最多 10 位小数点后两位。不要用 DOUBLE更不要用 VARCHAR 存金额面试官只要看到金额字段类型里有 FLOAT 或 DOUBLE就知道你没踩过精度坑。时间DATETIME 配 DEFAULT CURRENT_TIMESTAMP插入时自动带当前时间不用在 Java 代码里手动 new Date()这个习惯能省掉一批时间格式化的问题。索引外键列比如 category_id 必加普通索引status 这种经常出现在 WHERE 条件里的列也可以加。但别给 TEXT 列加索引后面数据量上来了再用全文索引也不迟。排序和统计交给 SQL 的 ORDER BY 和 GROUP BY不要想着把数据拉回 Java 内存里用 Collections.sort() 排数据库干这个活比 Java 快得多而且语句写出来一目了然。注意user 在 MySQL 里有关键字的身份建表时最好用反引号包起来或者直接把表名改成 tb_user、sys_user。项目里统一命名别一会 user 一会 sys_user后期对 SQL 会很难受。3.3 数据流串讲从小程序首页到下单的完整链路把六张表串起来就是一条完整的数据流。小程序首页打开时先请求分类列表再带分类参数请求作品分页数据点进详情页可以收藏也可以下单收藏记录落在 favorite 表订单落在 orders 表。首页 → GET /api/category/list → category 表 → GET /api/paper-cut/list?page1 → paper_cut 表where status 1 详情 → GET /api/paper-cut/detail/:id → paper_cut 表 收藏 → POST /api/favorite/toggle → favorite 表记录 userId paperCutId 下单 → POST /api/order/create → orders 表更新销量和库存这条链路的数据库增删改查覆盖了大部分毕设要求列表分页是查收藏是新增和删除下单是事务里先查库存再更新销量。做的时候注意一点收藏和订单这类接口后端必须从当前登录态里拿 userId不能只靠前端传一个 userId 过来否则数据对不上人答辩时被问「你怎么保证是本人操作」就答不上来。订单表一般长这样order_no 订单号、user_id、paper_cut_id、amount 金额、status 状态0 待支付、1 已支付、2 已取消、create_time。订单号别用自增 ID用时间戳加随机数拼一个显得正规也好跟用户解释。3.4 用 SQL 验证数据统计、排序与 MySQL 修改表结构项目跑起来后先用 SQL 把数据过一遍确认后端查出来的结果和库里是一致的。这一步花十分钟能挡掉后面很多「接口报错到底是数据问题还是代码问题」的纠结。-- 按分类统计作品数LEFT JOIN 保证分类没有作品时也能显示 SELECT c.name, COUNT(p.id) AS cnt FROM category c LEFT JOIN paper_cut p ON c.id p.category_id GROUP BY c.id; -- 销量排行前五上架状态才参与排序 SELECT title, sales, price FROM paper_cut WHERE status 1 ORDER BY sales DESC LIMIT 5; -- 给作品表临时加库存字段ALTER TABLE 会重建整张表 ALTER TABLE paper_cut ADD COLUMN stock INT DEFAULT 0 COMMENT 库存;说明ALTER TABLE 修改结构也就是常说的 MySQL 修改表结构在数据量大的表上有锁表风险。毕设几千行数据无所谓但你要能答上来这个知识点——ALTER 会触发全表重建生产环境要选低峰期执行或者用在线 DDL 工具。能把这一层的利弊说出来老师会觉得你不只是会敲命令。导入数据库文件也是固定操作两行命令解决。# 先用 -e 执行一条建库 SQL再重定向导入 .sql 文件 mysql -u root -p -e CREATE DATABASE IF NOT EXISTS papercut DEFAULT CHARSET utf8mb4; mysql -u root -p papercut /path/to/papercut.sql参数说明-e 是执行单条 SQL 是重定向把文件内容灌进数据库。如果 .sql 文件里已经有 CREATE DATABASE 语句直接执行第二条就行不用先建库。导入中文乱码时检查 .sql 文件顶部的注释和建表语句里的 DEFAULT CHARSET两边都得是 utf8mb4 才对得上。4. 微信小程序端对接登录、列表加载更多与顶部导航适配4.1 小程序目录结构与 app.js 全局配置后端接口就绪后看小程序端。拿到源码包先看目录结构能快速判断项目维护得好不好页面是不是按业务拆的公共请求有没有单独抽出来。miniprogram/ ├── pages/ │ ├── index/ # 首页作品瀑布流 │ ├── category/ # 分类页 │ ├── detail/ # 作品详情 │ ├── favorite/ # 我的收藏 │ └── user/ # 个人中心 ├── utils/ │ └── request.js # 统一请求封装 ├── app.js # 全局逻辑登录态、全局数据 ├── app.json # 全局配置页面注册、窗口样式 └── project.config.jsonapp.json 里的 pages 数组第一项就是启动页这个设置经常被忽略——想把首页换成个人中心调整数组顺序就行。window 节点里的 navigationBarBackgroundColor 和 navigationBarTitleText 控制的是顶部导航栏样式后面做自定义导航适配时会用到。{ pages: [pages/index/index, pages/category/category, pages/detail/detail, pages/favorite/favorite, pages/user/user], window: { navigationBarTitleText: 中国剪纸, navigationBarBackgroundColor: #C0392B, navigationBarTextStyle: white } }说明navigationBarTextStyle 只能写 white 或 black写别的颜色不会生效这是微信的硬限制。如果你看到某个页面顶栏颜色和全局不一样去对应页面的 .json 文件里查它有没有单独配 navigationBarTitleText页面级配置会覆盖全局。4.2 封装 wx.requestbaseURL、超时与 token 注入小程序没有 axios所有网络请求都要走 wx.request。最省事的做法是封一个 request.js把 baseURL、超时、token、错误处理全部收口页面里只关心业务逻辑不用每次都拼 URL 和 header。const BASE_URL http://192.168.1.100:8080/papercut; function request(path, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL path, method, data, header: { Content-Type: application/json, token: wx.getStorageSync(token) || }, timeout: 10000, success(res) { if (res.data.code 200) { resolve(res.data.data); } else if (res.data.code 401) { // 登录态失效清掉 token跳回个人中心 wx.removeStorageSync(token); wx.navigateTo({ url: /pages/user/user }); reject(new Error(未登录)); } else { wx.showToast({ title: res.data.msg, icon: none }); reject(new Error(res.data.msg)); } }, fail(err) { // 开发期最常见的失败原因后端没启动、IP不对、没开跨域 wx.showToast({ title: 网络请求失败, icon: none }); reject(err); } }); }); } module.exports { request, BASE_URL };参数说明BASE_URL 里必须带项目部署名/papercut很多 404 就是漏了这一段。token 从本地存储里取没有就传空字符串后端接口没有拦截器时会正常放行加了拦截就返回 401 走重新登录。timeout 给 10 秒开发期后端第一次编译启动比较慢设太短容易误报超时。真机预览时网络请求失败先查 BASE_URL 是不是局域网 IP 而不是 localhost——手机访问不到电脑的 localhost。4.3 首页作品列表下拉刷新与触底加载更多小程序页面列表加载更多是面试和答辩常客实现思路一句话页面触底时页码加一请求下一页把返回的数据拼到当前数组后面没有更多数据时停住。这里贴一个完整的最小实现。Page({ data: { list: [], page: 1, pageSize: 10, hasMore: true, loading: false }, loadList() { if (!this.data.hasMore || this.data.loading) return Promise.resolve(); this.setData({ loading: true }); return request(/api/paper-cut/list?page${this.data.page}size${this.data.pageSize}) .then((data) { // data.list 是后端返回的当前页数据拼到已有数组后面 this.setData({ list: this.data.list.concat(data.list), page: this.data.page 1, hasMore: data.list.length this.data.pageSize, loading: false }); }) .catch(() { this.setData({ loading: false }); }); }, onPullDownRefresh() { // 下拉刷新重置页码和数据再重新请求 this.setData({ list: [], page: 1, hasMore: true }); this.loadList().then(() wx.stopPullDownRefresh()); }, onReachBottom() { this.loadList(); } });说明loading 标志是关键没有它触底回调连续触发时会发出大量重复请求。hasMore 的判断用「返回条数等于 pageSize」而不是「总数除以页码」因为后一种写法每次都要多查一次 COUNT毕设量级无所谓但这是接口设计上的习惯问题。注意一个边界如果最后一页正好等于 pageSize会多请求一次空页业务上无感不需要专门处理。下拉刷新则要先重置页码和列表再重新拉第一页。页面 wxml 里用wx:for渲染 list记得给wx:key绑 id否则列表重排时性能会明显变差这是小白最容易忽略的。4.4 顶部导航栏高度刘海屏适配的两种取值方式小程序顶部导航栏高度不是固定值跟机型、是否有刘海屏都有关系。默认导航栏一般不用管但如果你要做自定义导航或者把页面做成沉浸式就必须自己算导航栏高度了。function getNavBarInfo() { const sys wx.getSystemInfoSync(); const menu wx.getMenuButtonBoundingClientRect(); // 顶部状态栏高度iOS 和安卓不一样 const statusBarHeight sys.statusBarHeight; // 导航栏高度 胶囊上下留白之和 胶囊高度 const navBarHeight (menu.top - statusBarHeight) * 2 menu.height; return { statusBarHeight, navBarHeight, menuRight: sys.windowWidth - menu.left }; }说明这套算法是社区里的标准做法——胶囊按钮在导航栏区域里垂直居中用胶囊的 top 减去状态栏高度得到胶囊上方的间距由于上下间距相等乘以 2 再加胶囊高度就是导航栏的总高度。menuRight 是给右侧胶囊留白用的自定义按钮要避开这个区域否则会被微信的菜单盖住。真机上看到的高度和模拟器不一样是正常的以真机调试为准别在模拟器上纠结那几像素。5. SSM小程序联调避坑5 个让你翻车的真实问题5.1 小程序请求全部 404上下文路径没对齐现象开发者工具里打开首页列表空白控制台一排 404但同一个地址复制到浏览器里能正常返回 JSON。原因后端部署在 Tomcat 时项目名是 papercut而小程序 BASE_URL 写的是http://ip:8080/少了中间的项目上下文路径。SpringMVC 的 RequestMapping 只管方法路径不管项目部署名两头一拼接就成了http://ip:8080/api/...Tomcat 找不到对应的 web 应用。解决BASE_URL 统一写成http://ip:8080/papercut/路径末尾的斜杠可带可不带但全局必须一致。排查时先在浏览器直接访问http://ip:8080/papercut/api/paper-cut/list?page1能返回 JSON 再怀疑小程序端否则先查 Tomcat 部署名和 context-path 配置。5.2 数据表中文乱码连接串少了一个参数现象后端往数据库插的中文查出来全是问号英文正常或者小程序传中文到后端收下来是乱码。原因JDBC 连接串里没有 characterEncodingutf8MySQL 的默认连接字符集跟表字符集对不上。另一个来源是建表时没写 DEFAULT CHARSETutf8mb4用了 MySQL 默认的 latin1。解决URL 统一改成jdbc:mysql://localhost:3306/papercut?characterEncodingutf8建表语句全部带 DEFAULT CHARSETutf8mb4。已经乱掉的表改字符集后之前存进去的乱码数据也回不来了只能删掉重新导入所以这个参数要在项目一开始就配上不要等数据量大了再处理。5.3 上传的剪纸图片不显示静态资源映射没配现象后台上传接口返回了图片地址/upload/xxx.jpg小程序 image 组件加载这个地址报 404。原因DispatcherServlet 配置成/接管了所有请求/upload/**也被拦截了SpringMVC 找不到对应的 Handler直接 404。图片文件其实好好躺在磁盘上只是访问不到。解决在 springmvc.xml 里放行静态资源。!-- location 指向图片实际存放的磁盘目录不要写成 classpath -- mvc:resources mapping/upload/** locationfile:/D:/upload//参数说明location 指到的是文件实际存放目录不是 Tomcat 的 webapp 目录。配完要重启 Tomcat 才生效。还有一种偷懒做法是把图片存到项目的 webapp/upload 下面IDE 里跑没问题打成 war 包部署后图片一重启就丢不推荐。5.4 MyBatis 查询返回 null驼峰映射未开启现象接口返回 200数据库里有值但 JSON 里一半字段是 null最典型的是 create_time、cover_url 这类带下划线的列。原因实体类属性是 createTime、coverUrl表字段是 create_time、cover_urlMyBatis 默认不会自动把下划线转驼峰resultType 自动映射时找不到对应的 setter就静默地置成 null。解决在 MyBatis 配置文件里开全局驼峰映射。settings setting namemapUnderscoreToCamelCase valuetrue/ /settings说明配了这个设置select 返回的列名只要去掉下划线能对上属性名就不用手写 resultMap。注意如果项目里已经有手写的 resultMap这个设置不会覆盖显式映射改了没反应就去检查 resultMap 的 column 和 property 有没有写错。5.5 真机预览连不上后端合法域名与调试模式现象开发者工具里一切正常一真机预览就所有请求失败页面空白控制台全是 request:fail。原因开发者工具里勾了「不校验合法域名」本机调试能放行真机上所有请求域名必须是小程序后台配置过的 HTTPS 合法域名。毕设用的是http://ip:8080既不是 HTTPS 也没有备案域名直接被微信拦截。解决开发调试阶段小程序右上角菜单里选「开发版」点开右上角胶囊按钮进入调试模式真机请求会暂时绕过域名校验正式上线则必须在小程序管理后台配置 request 合法域名并且服务器上要有 HTTPS 证书。这个坑和代码无关但最容易在演示前一晚把人卡住提前用真机验证一遍最稳妥。6. 把交付包变成答辩高分素材一套可复现的演示脚本源码包里的 PPT、开题报告、使用文档和演示视频不是让你直接交上去的而是让你拆出一套自己的演示流程。我的做法是先把演示视频完整看一遍记下操作顺序启动 MySQL、导入 SQL、启动 Tomcat、打开开发者工具、登录、浏览列表、点进详情、下单。然后照着这个顺序自己走三遍直到不用看笔记也能顺下来。演示前必须干一件事准备一份演示专用数据。用下面这条 SQL 把状态重置保证现场无论点多少次都不会出现「库存不足」或者「订单列表太乱」的尴尬。UPDATE paper_cut SET stock 20, sales 0 WHERE status 1; DELETE FROM orders; DELETE FROM favorite;参数说明下线状态的作品不碰只清演示会用到的订单和收藏分类和作品数据留着展示。DELETE 前可以先 SELECT 确认要清的表名别把用户表也删了那现场就直接白屏。答辩时老师大概率会问「这个项目哪些是你做的」别回答「都是一个人做的」这种话。你要能指着 PPT 里的架构图从登录鉴权的调用链、列表分页的加载更多、订单事务的扣库存这三块各讲两分钟每一块都能落到具体的类和 SQL 上这就足够了。PPT 里的表关系图也提前对着数据库核对一遍数据字典里字段名和库里不一致的话记得改。我第一次答辩就翻车在现场 MySQL 服务没启动台上打开项目白屏从那以后我习惯把 MySQL 设成开机自启演示前先跑一句健康检查命令确认服务活着再开始讲。希望帮到你。本文还有配套的精品资源点击获取
返回列表