ARTICLE DETAIL

资讯详情

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

基于SpringBoot+SSM的美食分享平台设计与实现——从搭建到部署详解

基于SpringBoot+SSM的美食分享平台设计与实现——从搭建到部署详解 做美食分享平台这个项目最初是帮学生做课程设计时接的活。需求很常见注册登录、发菜谱、传图片、评论收藏、管理员审核再加上一套能跑通的前后端流程。技术栈点名要 Java SpringBoot SSM也就是 Spring、SpringMVC、MyBatis 这一套东西。今天我把整套工程从搭建、编码到排错部署的细节捋一遍很多坑是文档和视频里不会写的结合我实际调试项目时遇到的问题尽量一次讲透。先给个结论这套系统不算复杂但涉及的技术点很典型——SpringBoot 自动装配、SSM 三层结构、MyBatis 映射、上传文件、拦截器、后台统计、部署打包几乎把 JavaWeb 后端开发的主干知识都覆盖了。不管是做毕业设计、课程项目还是面试准备都能从中找到能聊的东西。如果你拿到的源码包里带着 SQL、LW 论文和调试文档那更省事但要是不理解里面每个模块为什么这么写出现问题照样一头雾水。所以这篇文章不打算只给你看项目截图而是把“为什么这么选型”“代码里哪些地方容易出事”“拿到项目后怎么快速调通”都讲明白。1. 项目整体设计与技术选型1.1 为什么选 SpringBoot SSM 这套组合很多人在选型时会纠结都 2025 年了为什么不直接 Spring Boot MyBatis-Plus还要提 SSM这里有个背景课程设计和毕业设计通常要求体现“SSM 框架”甚至任务书里会明确写“基于 SpringSpringMVCMyBatis”。SSM 是 JavaEE 开发里非常经典的一套组合Spring 管对象和事务SpringMVC 管请求分发MyBatis 管数据库访问。SpringBoot 本身不是一个取代 SSM 的框架它更像是把 Spring 家族粘合在一起的启动器。实际上 SpringBoot 项目里完全可以使用 SSM 的组合方式只是不再需要写一堆spring-mvc.xml、mybatis-config.xml配置文件。SpringBoot 用自动配置把 SpringMVC 和 MyBatis 集成好了我们只需要在application.yml里配数据源和 mapper 扫描路径。所以这个项目对外可以说是“基于 SpringBoot 的 SSM 架构”对内仍然能体现 Service、Mapper、Controller 三层结构。这个点面试时经常被问到能解释清楚是一个加分项。选型时我还特意固定了 JDK 版本。SpringBoot 2.7.x 配 JDK 8 是最稳的组合SpringBoot 3.x 开始强制 JDK 17很多培训机构模板或者教学代码还是基于 JDK 8 写的版本不对会导致莫名其妙的编译错误。这个项目里我采用 SpringBoot 2.7.18 JDK 1.8 MyBatis MySQL 5.7/8.0兼容性最好Maven 依赖也容易拉。1.2 功能模块与角色划分这个美食分享平台从需求上讲分前台用户端和后台管理端。普通用户可以浏览美食菜谱、按分类筛选、注册登录、发布带图片的菜谱、收藏喜欢的菜谱、给菜谱评论、关注其他用户。管理员则负责管理分类、审核菜谱、管理用户评论、查看基础统计信息。如果把功能拆细一点大概是这几个模块。用户模块注册、登录、退出、个人信息修改、密码加密存储。菜谱模块发布菜谱、编辑菜谱、支持图片上传、菜谱列表分页、详情查看。分类模块菜系分类比如川菜、粤菜、烘焙、甜品管理员维护。互动模块评论、回复、收藏、点赞。后台管理模块用户管理、菜谱审核发布后能不能上架展示、分类管理、数据概览。搜索模块按菜谱名称、分类关键词模糊搜索。我最初设计时没有做用户关注和私信因为工作量会明显增加。如果你想要让系统显得更完整可以在用户表加一个follow表或者做成简单的关注关系。但单从课程设计评分点来看评论收藏和管理员审核已经足够覆盖常见的 CRUD 和关联表操作了。1.3 数据库设计核心表结构美食分享平台的数据量不会很大但表关系还是要清楚。我规划了这样几张核心表用户表user、分类表category、菜谱表recipe、评论表comment、收藏表favorite。如果要做点赞再加一张recipe_like表。用户表字段基本是这些id、username、password加密后的密文、nickname、avatar、role0 普通用户1 管理员、create_time。密码一定不能明文存储项目里我用的是 MD5 加盐的方式也可以在 SpringSecurity 里用 BCrypt但当前项目不引入安全框架MD5 加盐对课程设计完全够用。菜谱表是核心表字段包括id、user_id、category_id、title、intro、ingredients食材清单可以用长文本、steps步骤描述也可以用长文本、cover_image封面图、create_time、status0 待审核1 已发布2 审核不通过。评论表关联用户和菜谱收藏表则是用户和菜谱的多对多关系唯一约束一定要加在user_id和recipe_id的组合上不然用户重复点击收藏会产生一堆脏数据。下面是我实际用的建表 SQL 片段可以给你参考。CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50) NOT NULL, password VARCHAR(255) NOT NULL COMMENT 加盐后的密码, nickname VARCHAR(50) DEFAULT NULL, avatar VARCHAR(255) DEFAULT NULL, role TINYINT DEFAULT 0 COMMENT 0用户 1管理员, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE recipe ( id INT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, category_id INT DEFAULT NULL, title VARCHAR(100) NOT NULL, intro VARCHAR(500) DEFAULT NULL, ingredients TEXT, steps TEXT, cover_image VARCHAR(255) DEFAULT NULL, status TINYINT DEFAULT 0 COMMENT 0待审核 1发布 2驳回, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_category_id (category_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这里有一个细节所有表字段我统一用utf8mb4不要用utf8否则 emoji 表情和部分生僻字会存不进去美食类项目用户经常会在菜谱描述里放特殊符号踩过坑的都懂。2. 环境准备与工程搭建2.1 JDK、Maven、IDEA 配置要点Java 环境变量配置是老生常谈但很多新手就在这卡住。项目要求 JDK 1.8 或 8你要保证java -version显示的是 1.8。Windows 环境下配环境变量时JAVA_HOME路径不要带末尾的反斜杠Path里加%JAVA_HOME%\bin。装完一定重新开终端因为环境变量不会自动刷新。Maven 我建议直接装一个本地仓库并用阿里云镜像不然拉 SpringBoot 依赖会慢到怀疑人生。IDEA 里导入项目时注意File - Project Structure - Project SDK要选择 1.8Settings - Build Tools - Maven - Importing里也要把 JDK 和 Runner 的 JRE 指对。很多时候代码没错就是 IDEA 默认给了 JDK 17编译直接报错。还有一点如果你在 terminal 里执行mvn -v也要确认当前默认 JDK 是 8。Maven 这个工具不认你的JAVA_HOME配置就可能会用错版本后面会出现“源发行版 17 需要目标发行版 17”这类恶心报错后面我会专门讲。2.2 工程骨架生成与依赖导入SpringBoot 项目推荐直接用 Spring Initializr 生成IDEA 内置就有也可以到 start.spring.io 手动选版本。项目名称我取的是food-sharing-platformgroupId 可以写com.exampleartifact 按项目名来。生成后的pom.xml核心依赖主要是这些。parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version relativePath/ /parent dependencies !-- Web 启动器 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- MyBatis 集成 -- dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.3.1/version /dependency !-- MySQL 驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency !-- Lombok 简化代码 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies这里我故意没有引入spring-boot-starter-security因为小型项目引入它反而增加理解成本。权限控制用拦截器实现够用且更容易在答辩时讲清楚。2.3 传统 SSM 配置如何迁移到 SpringBoot传统的 SSM 项目里会有一堆 XMLspring-mvc.xml、spring-mybatis.xml、web.xml、mybatis-config.xml。SpringBoot 项目只需要一个application.yml就能代替大部分配置。我写的配置大概是这样server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/food_share?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource servlet: multipart: max-file-size: 10MB max-request-size: 20MB mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.food.entity configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl在这个配置文件里我把 MyBatis 的 mapper XML 路径指定到classpath:mapper/*.xml实体类别名放在com.example.food.entity。map-underscore-to-camel-case必须开这样数据库的user_id才能自动映射到实体类的userId不然后端查出来全是 null。如果你还要体现“SpringMVC 配置”可以在启动类上加MapperScan(com.example.food.mapper)扫描 Mapper 接口再用Configuration写一个 WebMvcConfigurer 放拦截器。这是比较标准的做法也保留了 SSM 分层的痕迹。3. 核心功能实现从登录到发布菜谱3.1 注册登录与密码加密用户注册是入口也是最容易写得不安全的地方。我项目里没有明文密码而是用 MD5 固定盐的方式做加密。工具类里写了一个MD5Util大概是这样public class MD5Util { private static final String SALT foodShare2025; public static String encrypt(String input) { String base SALT input; return DigestUtils.md5DigestAsHex(base.getBytes(StandardCharsets.UTF_8)); } }注册时先判断用户名是否重复重复就返回提示不重复则存加密后的密码。登录时用相同规则加密后去数据库对比。这种方式虽然不如 BCrypt 强但在项目里足够防止直接看到密码明文而且实现简单答辩时能讲清楚盐的作用。权限控制我用了 Spring MVC 的拦截器。写一个LoginInterceptor在preHandle方法里从 session 拿用户对象拿不到就重定向到登录页。管理员接口再判断session里用户的role是否为 1。拦截器要注册进去同时放行登录、注册、首页、菜谱列表、图片访问这些路径。3.2 菜谱发布流程与图片上传用户登录后可以进入发布菜谱页面表单里要选分类、填标题、填简介、填食材、填步骤还要上传一张封面图。这里最核心的是图片上传处理。SpringBoot 里接收上传文件很简单Controller 方法用MultipartFile接收然后保存到本地磁盘。但这里有几个坑要提前清楚。第一保存路径不要用工程根目录下的临时文件夹因为打包成 jar 后写不进去。我习惯把图片存到服务器上的固定目录比如D:/food-upload/再通过资源配置让它能被浏览器访问。第二文件名一定重命名避免中文乱码和重复。我用了 UUID 加原始文件后缀名String originalFilename file.getOriginalFilename(); String ext ; if (originalFilename ! null originalFilename.contains(.)) { ext originalFilename.substring(originalFilename.lastIndexOf(.)); } String newName UUID.randomUUID().toString().replace(-, ) ext; file.transferTo(new File(uploadDir, newName));第三要让上传后的图片能被页面访问需要写一个 WebMvc 配置类把/upload/**映射到物理路径Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceLocations(file:D:/food-upload/); } }发布菜谱时数据库里的cover_image只存相对路径比如/upload/xxx.jpg页面直接用这个路径访问。这样设计的好处是未来换 OSS 或者加 CDN只需要改变资源映射方式代码改动量很小。3.3 评论、收藏与点赞的交互评论和收藏是比较常见的关联表操作。评论表里的字段有user_id、recipe_id、content、create_time。查某个菜谱的评论列表时直接关联用户表查昵称和头像。收藏的典型逻辑是这样的用户点收藏先查favorite表里有没有记录有就表示已经收藏再次点击取消收藏。所以两个核心方法就是makeFavorite和cancelFavorite。为了提高效率我在favorite表建了联合唯一索引ALTER TABLE favorite ADD UNIQUE KEY uk_user_recipe(user_id, recipe_id);这样不光是防重复插入时即便出现了并发重复数据库也能把住最后一道关。点赞我一开始用了一张like_record表后来觉得课程设计阶段完全可以用数字字段解决比如在recipe表加一个like_count字段。但如果你要展示更多实现细节建议单独一张recipe_like表这样可以判断当前用户是否点过赞前端能回显红心状态。3.4 后台管理分类、审核与统计后台管理端不需要单独做一套前端我用的就是同一个 SpringBoot 项目只是访问/admin/**时会走管理员的拦截器。普通用户菜单里不会显示后台入口管理员登录后能看到用户列表、厨谱审核列表、分类管理这些页面。审核机制是这个项目里相对出彩的功能。用户发布的菜谱默认status 0前台只展示status 1的菜谱。管理员在后台看到待审核菜谱可以选择通过或驳回。驳回时如果能写一个驳回理由字段就更完整我在表里加了一个audit_remark字段但没做强制必填。数据统计也是后台的加分项统计总用户数、总菜谱数、总评论数再按分类统计菜谱数量。用 MyBatis 写一个聚合查询就行select idcountRecipeByCategory resultTypemap SELECT c.name AS categoryName, COUNT(r.id) AS recipeCount FROM category c LEFT JOIN recipe r ON c.id r.category_id AND r.status 1 GROUP BY c.id, c.name /select这个聚合 SQL 用LEFT JOIN是为了让没有菜谱的分类也显示出来后台页面上能看到“某个分类目前还是空的”一眼看出内容覆盖面。4. 调试、排错与性能优化4.1 启动卡死MySQL 连接与端口占用项目最常出问题的地方不在代码而在启动环境。我第一次跑这个项目时控制台一直卡在HikariPool - Start completed之前的日志也不报错看起来就像死循环。后来才发现是 MySQL 没有启动或者application.yml里的数据库密码和本地对不上。如果你遇到启动不报错但是卡住第一反应先去查数据库连没连上。另外还有一个很常见的坑就是端口被占用。SpringBoot 默认 8080如果你本地装了其他服务占了端口需要改server.port或者把占用端口的进程杀掉。查端口占用用netstat -ano | findstr 8080Windows 下很方便。4.2 JDK 版本过高导致的编译失败这个报错我基本每次帮人看项目都会遇到而且提示信息很明确java: 警告: 源发行版 17 需要目标发行版 17出现这个问题的原因大多是 IDEA 里项目的字节码版本是 17但你的依赖或者本地 JDK 只有 8。解决方式很简单三个地方全部改成 1.8File - Project Structure - ProjectSDK 设为 1.8File - Project Structure - ModulesLanguage level 设为 8Settings - Build Tools - Maven - RunnerJRE 设为 1.8同时pom.xml里加上properties java.version1.8/java.version maven.compiler.source1.8/maven.compiler.source maven.compiler.target1.8/maven.compiler.target /properties如果你用的是 SpringBoot 3.x那对应的就是 JDK 17此时想强制改成 JDK 8 也没用因为 SpringBoot 3 底层依赖就是 Java 17 起步。所以遇到这个问题先看 SpringBoot 版本不要盲目改 JDK。项目里我用的是 2.7.18配合 JDK 8 是最省心的。4.3 MyBatis 映射文件绑定异常与排查另一个高频报错是启动的时候提示Invalid bound statement (not found): com.example.food.mapper.RecipeMapper.findAll这个报错九成是 mapper XML 没有编译到目标目录或者 XML 里的 namespace 跟 Mapper 接口的全限定名不一致。我在项目里把 XML 都放在src/main/resources/mapper/下面但是有的新手习惯把 XML 放到和 Mapper 接口同一个包下面结果配置文件里mapper-locations又没扫描到就会出现这个错。排查步骤建议按顺序来打开 target/classes 目录看看 mapper 的 XML 有没有被打包进去。检查mapper-locations: classpath:mapper/*.xml路径是否对吗打开 XML看namespace是不是com.example.food.mapper.RecipeMapper。检查 XML 里的id和接口方法名是否完全一致包括大小写。还有一种比较隐蔽的情况接口方法用了Param注解XML 里却没有使用对应参数占位符导致参数绑定不上。MyBatis 对参数命名很敏感建议在接口方法里所有参数都加Param(xxx)不要在 XML 里用#{param1}这种数字。4.4 XSS 与 SQL 注入防范项目如果只是演示也许没人会去攻击但作为一套拿得出手的东西安全意识必须体现在代码里。XSS 攻击最常见的场景是用户评论框里填了一段script标签然后在其他用户页面上执行。解决方案是在进入后端的时候对请求参数做转义。我在项目里加了一个全局过滤器继承OncePerRequestFilter将HttpServletRequest包装成自定义的XssHttpServletRequestWrapper在getParameter方法里对参数值做 HTML 转义。public class XssFilter extends OncePerRequestFilter { Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { chain.doFilter(new XssHttpServletRequestWrapper(request), response); } }包装类里的转义逻辑就是用HtmlUtils.htmlEscape(value)把、、单引号、双引号等字符替换成实体编码。这样存进数据库的内容是转义后的页面上即使不经过模板引擎也会被浏览器当作文本展示。SQL 注入不需要额外写什么因为 MyBatis 里使用#{}预编译已经防止了大部分注入但要注意在${}场景比如排序字段、动态表名等千万不要直接拼接用户输入。这个项目里我统一用了#{}没有用${}。4.5 日志与断点调试技巧遇到问题不要光看print输出。项目里我在application.yml中设置了 MyBatis 的log-impl: StdOutImpl这样控制台能看到每个 SQL 和参数。这是排查数据库问题最快的途径。当某个查询返回 null 或者报错时先把 SQL 日志打开看最终执行的 SQL 长什么样很多时候问题就出在参数上。IDEA 断点调试则主要用于排查业务逻辑跳转异常。比如用户登录后跳转回首页结果不对直接在 Controller 方法里打断点看返回值是什么、请求参数有没有传递过去。对于前后端不分离的项目还要看ResponseBody会不会影响视图跳转我自己就在这犯过糊涂很多新手一上来就在 LoginController 上加大RestController结果所有方法都返回 JSON页面完全渲染不出来。5. 部署上线与演示注意事项5.1 打包方式jar 还是 warSpringBoot 默认打 jar 包用mvn clean package就可以。之后在生产环境直接java -jar food-sharing-platform-0.0.1-SNAPSHOT.jar如果你部署的服务器没有 8080 端口可用启动时加参数java -jar xxx.jar --server.port8081但有些课程设计环境强制要求部署到传统 Tomcat这时候需要把pom.xml里的打包方式改为war同时让启动类继承SpringBootServletInitializer并重写configure方法。其实我建议优先用 jar 方式更简单也更能体现 SpringBoot 的内嵌容器优势。5.2 数据库初始化和文档配套拿到项目之后第一件要做的事就是把 SQL 文件导入数据库。不要只导入表结构还要把初始化数据一起导进去否则前端页面空空如也看起来非常不完整。我在 SQL 文件里预置了一个管理员账号和几个测试用户管理员用户名 admin初始密码 123456菜谱分类和几条示例菜谱也一并写好。写完代码配套的 LW论文和调试文档也很重要。如果你的项目包含了毕业论文里面建议画好 ER 图、系统流程图、功能结构图。答辩时老师最喜欢问“你这个表为什么这么设计”“你这个功能怎么实现的”。把数据库关系和核心业务流程讲清楚比堆代码更得分。5.3 Nginx 反向代理与图片访问路径项目部署到服务器后如果你希望上传的图片能稳定访问不建议直接把 SpringBoot 的静态资源映射暴露给公网。更规范的做法是在前面加一层 Nginx把/upload/路径映射到服务器的物理目录。比如图片上传到D:/food-upload/Nginx 配置可以这样写location /upload/ { alias D:/food-upload/; expires 7d; add_header Cache-Control public; }然后 SpringBoot 里的资源映射可以取消或者保留都行但是 Nginx 优先会接管对应请求。这样好处是图片访问不再占用后端应用线程而且 Nginx 自带缓存页面加载速度明显更快。如果是在 Windows 本机演示不做 Nginx 也没关系但部署到 Linux 服务器时这个步骤值得加上。6. 常见问题速查表与个人心得6.1 一组高频报错速查表我把项目调试过程中最常踩的问题整理成一个表格基本上能覆盖 80% 的启动和运行异常。报错或现象原因解决方法启动卡住但不报错数据库没启动或连接配置错误启动 MySQL检查账号密码和连接 URLjava: 源发行版 17 需要目标发行版 17IDEA 或 Maven 用了高版本 JDKProject Structure 和 Maven Runner 全部改成 1.8Invalid bound statement (not found)mapper XML 没打包或 namespace 写错检查编译目录和 XML namespace页面图片显示 404静态资源映射没配置配置 addResourceHandlers 或 Nginx alias中文乱码URL 编码或数据库编码不一致使用 utf8mb4配置 characterEncodingutf8上传文件过大报错文件大小超过默认限制修改 multipart max-file-size 和 max-request-size登录后页面不跳转Controller 返回 JSON 而非视图检查是否使用 RestController 导致评论框的脚本被浏览器执行缺少 XSS 过滤增加全局 XssFilter 对参数转义这张表其实是我长期帮人debug的浓缩遇到问题先对号入座基本能省很多时间。如果你是拿到源码包直接打开也建议先把这些坑记在脑子里免得以为代码坏了其实只是环境没配对。6.2 拿到源码后的第一件事很多同学从网上下载项目源码之后第一反应是打开 idea 直接右键 run结果各种报错。我自己现在拿到任何项目第一件事永远是先看 README 或者项目说明里面写了版本要求、数据库导入方式照着做。然后打开application.yml把数据库账号密码改成自己的看看文件路径配置是不是需要创建对应的目录。接下来导入 SQL 文件确认数据库名和连接 URL 一致。最后启动项目看控制台日志有没有出现Tomcat started on port(s): 8080。这一步通过了说明核心环境没问题然后再去注册账号、发布菜谱。这里给一个很实用的小技巧双击 Ctrl 两次全局搜索项目里的 IP 和端口配置看看有没有写死别人的地址。有时候别人发的项目里配置的是他自己的服务器 IP你本地一启动肯定连不上搜到之后改成 localhost 或者自己的服务器地址。6.3 个人踩坑记录最后说几个我在实际调试这个美食分享平台时踩过的典型坑。第一个是图片上传路径问题。刚开始我直接把图片传到了项目目录下本地运行没问题可一旦打包成 jar 在服务器上跑就发现图片丢了或者根本没传上去。后来改成固定磁盘路径 资源映射问题才彻底解决。做这类项目的人最好一开始就规划外部存储别图省事。第二个是 MySQL 时区问题。如果 URL 里不加serverTimezoneAsia/Shanghai高版本 MySQL 会报时区错误甚至连连接都建立不了。这个错误信息很直接但如果不认识很容易以为是驱动版本不对。第三个是 Windows 和 Linux 的路径分隔符。代码里如果用File.separator拼接路径会更稳直接写死C:/或/tmp的话跨平台部署很容易出问题。我在代码里用System.getProperty(os.name)去判断也不是不行但最简单的还是写一个配置项把上传路径放到 yml 里部署时按环境改。第四个是接口返回格式不统一。项目初始阶段Service 层返回nullController 直接返回对象前端页面判断数据时经常摸不着头脑。后面我统一了返回结果类ResultT包含code、msg、data三个字段无论查询成功还是失败返回结构都是一致的。虽然这个项目没有强制要求但如果你想让代码看起来更专业很值得加。做这个美食分享平台技术上的核心积累其实不在某一个炫酷功能而在于你能否把登录、上传、评论、后台审核这些常规点做得稳妥遇到问题能一步步定位。SpringBoot 和 SSM 的搭配既保留了分层思想又降低了配置门槛很适合作为一套完整的 JavaWeb 练手项目。你在实际动手时如果做到图片上传、用户会话管理、Mapper 映射这些地方被卡住不妨回头再看一遍我前面写的排错思路多半能少走几段弯路。
返回列表