ARTICLE DETAIL

资讯详情

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

Spring Boot古风诗词社区系统开发实战:从数据库设计到部署交付

Spring Boot古风诗词社区系统开发实战:从数据库设计到部署交付 接到这套“古风生活体验交流网站系统”的时候我其实挺能猜到它的定位Java Spring Boot诗词鉴赏、古风文化交流附带源码、文档、运行视频和讲解视频。这类项目在课程设计、毕业设计里出现频率很高但真正能做到“功能完整、代码能跑、答辩能讲”的其实不多。很多同学拿到手要么跑不起来要么跑起来之后不知道每个模块在干什么更别提自己上手改代码了。这篇文章我就把这套系统的需求拆解、数据库设计、核心模块实现、部署打包以及录制演示视频和讲解视频的完整经验全部复盘一遍。无论你是要用它做毕设、课设还是想拿一个完整的Spring Boot项目练手这篇文章都能帮你少走很多弯路。我尽量用实际做项目时的口吻来讲不会堆砌概念。凡是涉及原理的地方都会说清楚“为什么这样选”凡是涉及代码的地方都会给出可直接参考的写法。你按照这篇文章的思路走一遍不仅能把这套系统跑起来还能在答辩或讲解的时候说出个一二三来。1. 给古风诗词网站“画像”业务场景与功能拆解很多拿到这类项目的人第一反应是急着看代码。我的建议是反过来先把业务场景想清楚。因为这套系统的名字“古风生活体验交流网站”听起来有点文艺但它本质上是一个内容社区——诗词是内容交流是社区。1.1 这个系统到底解决什么问题古风爱好者需要一个地方来分享诗词、交流赏析心得、了解作者背景。你把它类比成一个小型论坛加内容门户就很好理解了有人负责发布内容管理员录入诗词有人负责浏览内容游客和普通用户有人负责互动评论、点赞、收藏还有人需要管理一切管理员。这个定位直接决定了技术选型和功能边界。它不需要像电商系统那样处理复杂的订单流程也不需要像社交软件那样做即时通讯。它最核心的事情只有两件把诗词内容组织好把用户交流支撑起来。所以我在功能拆解时的思路是先划出三个端用户端、内容管理端、后台管理端再往每个端里填功能最后删掉那些“听起来很酷但对这个项目没必要”的功能。1.2 功能模块清单做什么、不做什么整套系统最终可以划分成下面这几个模块用户模块注册、登录、退出、个人中心、修改资料。游客只能浏览登录后才能评论和点赞。诗词模块诗词列表、诗词详情、按作者筛选、按朝代筛选、按标签检索、诗词搜索。作者模块作者列表、作者详情页展示作者生平和代表作。社区交流模块发布帖子、浏览帖子、帖子详情、评论、点赞、收藏。后台管理模块诗词管理增删改查、作者管理、用户管理、帖子管理、评论管理。需要注意这套系统里我没有做支付、没有做消息通知、没有做私信。原因很简单这些功能对古风诗词社区来说不是核心场景。加上了反而会成为累赘——代码量上去了但答辩时你说不清业务价值面试官或老师反而会追问一堆你答不上来的细节。做项目最忌讳的就是什么都想塞进去。一个能自圆其说的功能闭环远比十个半吊子的功能堆砌更有说服力。1.3 交付物拆分源码、文档、运行视频、讲解视频分别意味着什么这套项目标了“源码文档运行视频讲解视频”这个组合本身就透露了很多信息。它不是一个大厂生产项目而是一个教学性质的完整交付物。你在接手或复现的时候要清楚每一部分的价值源码是骨架解决的是“怎么实现”的问题。文档通常包括需求文档、设计文档、数据库说明、操作手册解决的是“怎么理解”的问题。运行视频解决的是“怎么跑起来”的问题一般会录制环境配置、启动过程、功能演示。讲解视频解决的是“怎么讲清楚”的问题通常是逐模块讲代码逻辑和设计思路。对一个课程设计或毕业设计来说这四个东西缺一个都不算完整。尤其是讲解视频很多同学自己做完了项目但录视频时不知道从哪讲起结果两三分钟就冷场。我在后面专门用一节来讲讲录制演示和讲解视频时应该按什么节奏来。2. 技术选型Spring Boot 模板引擎的组合逻辑技术选型是这类项目最不需要“炫技”的地方。你不需要用微服务不需要用分布式缓存更不需要上容器编排。Spring Boot 2.x MyBatis-Plus Thymeleaf MySQL 是这套系统最稳妥的组合。2.1 为什么是Spring Boot而不是其他框架这个问题要在答辩前想清楚。Spring Boot 的核心价值是“自动装配 约定优于配置”它把Spring MVC、事务管理、数据访问这些底层细节大部分封装好了你只需要关注业务代码。这一点对课程设计来说极其友好。对比一下传统的SSHStruts Spring Hibernate或SSMSpring Spring MVC MyBatisSpring Boot把XML配置量降到了极低内置Tomcat一条命令就能启动Web服务。对初学者来说这意味着你不需要理解Tomcat怎么部署WAR包也不需要纠结一堆XML配置的含义。对带项目的我来说这意味着交付给别人的东西更容易跑起来售后问题少一半。2.2 ORM选型MyBatis-Plus的理由数据访问层我选的是MyBatis-Plus。它有两个无可替代的优势第一单表CRUD完全不用写SQL。insert、deleteById、selectById、updateById这些方法内置就有直接继承BaseMapperT就能用。对诗词、作者、用户这种单表操作居多的场景开发效率提升非常明显。第二条件构造器QueryWrapper和LambdaQueryWrapper让动态查询写起来非常舒服。比如按朝代筛选、按标签筛选、按关键词搜索这些组合条件的SQL不用手动拼接用Wrapper就能处理得干干净净。对比纯MyBatis你每写一个查询都要维护XML映射文件项目做完光Mapper XML就几十个工作量翻倍。对比JPA/Hibernate虽然它也省SQL但它的实体映射和懒加载机制对初学者来说太容易踩坑而且生成SQL的不可控性在答辩时很容易被老师追问。MyBatis-Plus刚好卡在“够简单”和“够可控”之间。2.3 前端渲染Thymeleaf服务端渲染为什么比前后端分离更合适我知道现在很多公司项目已经前后端分离了Vue或React加上Spring Boot做纯后端API。但对这套古风诗词网站我坚决选Thymeleaf服务端渲染。原因有三条第一减少一套代码。前后端分离意味着你至少还要维护一个前端工程Vue项目需要Node环境、需要处理跨域、需要联调接口。服务端渲染则直接在Controller里返回视图名Spring Boot自动解析Thymeleaf模板一个工程全部搞定。第二SEO和首屏体验更好。网站的内容是诗词而这些内容需要被搜索引擎收录。服务端渲染直接把HTML返回给浏览器内容天然可见。前后端分离的SPA页面首屏全靠JS渲染对内容型网站不友好。第三对答辩和演示更友好。你用前后端分离演示时要同时启动前端Dev Server和后端服务遇到问题要查前端控制台和后端日志。服务端渲染只要启动一个8080端口所有页面都在。作为一个交付给别人的项目运行越简单越不容易出问题。这里多说一句Thymeleaf的语法也简单th:each做循环遍历、th:if做条件判断、th:text输出文本、{}处理URL路径。只要会基本的HTML基本一两天就能上手。3. 诗词内容模块古风数据的建模与检索这个系统最核心的内容域就是诗词。诗词的数据结构和其他业务数据不太一样它有几个天然的特点有朝代属性、有作者属性、有标签属性还可能有译文、注释、赏析等长文本。如果表结构设计得不好后面做列表、筛选、详情页会处处别扭。3.1 核心表结构设计我设计的时候拆成了四张核心表诗词表、作者表、分类/朝代表、标签表外加一张诗词与标签的关联表。这里最关键的一张表是诗词表它的主要字段如下CREATE TABLE poem ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键ID, title VARCHAR(128) NOT NULL COMMENT 诗词标题, author_id BIGINT NOT NULL COMMENT 作者ID, dynasty VARCHAR(32) NOT NULL COMMENT 朝代, content TEXT NOT NULL COMMENT 诗词正文, translation TEXT COMMENT 译文, annotation TEXT COMMENT 注释, appreciation TEXT COMMENT 赏析, cover_image VARCHAR(255) COMMENT 封面图URL, view_count INT DEFAULT 0 COMMENT 浏览量, like_count INT DEFAULT 0 COMMENT 点赞数, create_time DATETIME NOT NULL COMMENT 创建时间, update_time DATETIME NOT NULL COMMENT 更新时间, PRIMARY KEY (id), KEY idx_author_id (author_id), KEY idx_dynasty (dynasty) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT诗词表;有几点设计考量值得说清楚。第一朝代字段我直接冗余在诗词表里而不是单独建朝代表再外键关联。因为朝代总共就那么几个唐、宋、元、明、清、现代冗余字段可以少一次关联查询性能更好也不用担心数据不一致。第二作者ID用BIGINT而不是INT虽然当前数据量用INT完全够但养成用BIGINT的习惯可以避免将来数据量上来之后改表结构的痛苦。第三content、translation、annotation这些长文本统一用TEXT类型注意不要用VARCHAR去存大段赏析文本VARCHAR有长度上限而且超长文本在索引和排序时也有潜在问题。3.2 标签体系的多对多设计诗词的标签化是古风网站比较有代表性的需求。一首诗可以同时有“山水”“送别”“思乡”多个标签一个标签下也可以包含多首诗。这种多对多关系最标准的做法是中间表。CREATE TABLE poem_tag ( id BIGINT NOT NULL AUTO_INCREMENT, poem_id BIGINT NOT NULL, tag_id BIGINT NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_poem_tag (poem_id, tag_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT诗词标签关联表;代码里用MyBatis-Plus操作也很简单。查某个标签下的诗词列表可以先SELECT tag_id FROM tag WHERE name ?拿到标签ID再通过QueryWrapper查关联表拿到所有poem_id集合最后用selectBatchIds查出诗词列表。两步查询在数据量不大时完全够用不用纠结要不要写联表SQL。这里要注意一个细节UNIQUE KEY uk_poem_tag非常有必要。它保证同一首诗不会重复关联同一个标签这是数据完整性的底线。如果你不建这个唯一约束后面代码里多加一次判断都可能漏掉边界情况。3.3 诗词检索从LIKE到全文索引的演进诗词站点的搜索功能和一般标题搜索不太一样。用户可能搜“李白”找作者可能搜“静夜思”找标题可能搜“举头望明月”找诗句还可能搜“思乡”找主题。所以我的搜索实现分三种情况处理第一按标题搜索直接用等值或LIKE即可LambdaQueryWrapperPoem wrapper new LambdaQueryWrapper(); wrapper.like(Poem::getTitle, keyword);第二按诗词内容搜索比如搜“明月”要把所有包含“明月”的诗词列出来这时候还是LIKE查询但要注意content是TEXT类型LIKE的模糊匹配性能确实一般但数据量在万级以下时用户体验感知不到差异。第三按作者搜索需要先查作者表LambdaQueryWrapperAuthor authorWrapper new LambdaQueryWrapper(); authorWrapper.like(Author::getName, keyword); ListAuthor authors authorMapper.selectList(authorWrapper); ListLong authorIds authors.stream().map(Author::getId).collect(Collectors.toList()); if (authorIds.isEmpty()) { // 直接返回空避免后面拿着空集合构造SQL出错 return pageResult; } LambdaQueryWrapperPoem poemWrapper new LambdaQueryWrapper(); poemWrapper.in(Poem::getAuthorId, authorIds);如果追求更好的搜索体验可以引入Elasticsearch把诗词内容做成倒排索引但对这套系统来说属于“可以但没必要”。我在文档里会说明这个演进路径但实现层面用MySQL的LIKE合理索引已经完全满足需求。答辩时如果说得出“为什么不用ES”是一个加分项但如果用了ES却讲不清楚分词汇聚原理反而容易被问倒。3.4 诗词详情页上一篇/下一篇与相关推荐详情页除了展示诗词内容、译文、注释、赏析之外还有两个很常见的需求上一篇/下一篇翻页以及同标签下的相关推荐。上一篇/下一篇我用的是很朴素的思路按ID排序找比当前ID小的最大ID作为上一篇比当前ID大的最小ID作为下一篇。写成SQL就是SELECT * FROM poem WHERE id lt; #{currentId} ORDER BY id DESC LIMIT 1; SELECT * FROM poem WHERE id gt; #{currentId} ORDER BY id ASC LIMIT 1;但这个方法有两个边界条件要处理一是当前ID是最小或最大的那首诗查询结果为空页面要隐藏对应按钮二是在后台删除了某首诗之后ID之间会断档我这段SQL是按实际存在的数据去找不受断档影响这一点比直接id1要稳得多。相关推荐则是基于标签重叠度来做的先查出当前诗的所有标签ID再查关联表找出拥有这些标签的其他诗按重合数量降序取前5条。这个算法不复杂但效果很自然。至少比随机推荐有逻辑答辩时也讲得出设计思路。4. 社区交流模块发帖、评论、点赞的业务闭环古风网站的另一条腿是交流。我把它设计成一个轻量社区用户能发帖、能回帖、能点赞、能看自己的发帖列表。这个模块麻雀虽小五脏俱全是很多课程设计项目里老师最爱考察的地方。4.1 帖子、评论和点赞的数据模型帖子表的核心字段包括标题、内容、发布者ID、浏览数、点赞数、评论数、置顶标识、状态。评论表则要同时支持“帖子下的评论”所以它会有一个post_id字段和一个user_id字段。这里我想重点强调一个反直觉的设计点赞表要不要单独建我看到很多简化版项目直接把like_count字段存在帖子表里前端点一下赞就UPDATE post SET like_count like_count 1。这样做确实最简单但它有两个致命问题第一无法判断当前用户是否已经点过赞因为记录根本没存“谁点的赞”第二用户可以无限点赞只要不停调接口数据就是假的。所以我的做法是至少三张表配合帖子表存点赞总数冗余字段用于列表页展示点赞表存实际的“谁赞了哪个帖子”点赞时先查点赞表如果不存在则插入点赞记录并让帖子表的like_count加1。CREATE TABLE post_like ( id BIGINT NOT NULL AUTO_INCREMENT, post_id BIGINT NOT NULL, user_id BIGINT NOT NULL, create_time DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_user_post (post_id, user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT帖子点赞记录表;唯一约束uk_user_post是关键中的关键。哪怕你的代码在查询和插入之间存在并发间隙数据库这层唯一约束也能保证同一用户对同一帖子只能有一条点赞记录。这是双保险思路。4.2 点赞防刷数据库唯一约束是底线Redis是优化上面的设计能防住“重复点赞”但防不了“疯狂刷接口”。如果要在高并发场景下真正防刷可以在点赞接口里加Redis判断比如用SETNX命令以like:userId:postId为key第一次设置成功才允许点赞过期时间设为几分钟。但对这套系统来说我建议把Redis作为一个可选的加分项写入文档而不是一开始就引入。原因有两个第一引入Redis意味着搭建部署环境时要额外维护一个服务很多演示环境并不具备第二如果用了Redis却讲不清缓存和数据库一致性怎么保证答辩时被追问会很被动。我的实际做法是数据库表设计已经天然防住了重复点赞这个核心问题接口层做简单的频率限制比如判断创建时间间隔就够了。文档里我会提一句“如果要支撑高并发升级方案是引入Redis做点赞幂等再通过延迟批量写回数据库”这既展示了思考深度又不给自己挖坑。4.3 权限与安全游客、用户、管理员三种角色这个系统的角色我认为三种就够用了游客未登录、普通用户已登录、管理员。做不到复杂权限系统不重要重要的是把边界划清楚。我的权限控制分两层来做。第一层是拦截器层面登录拦截器检查需要登录才能访问的URL比如/post/add、/post/edit这些。第二层是业务逻辑层面就算请求能到达Controller也要再校验一次当前登录用户是不是帖子的作者防止有人通过直接构造URL去改别人的帖子。安全方面还有一个容易被忽略的点XSS攻击。用户在帖子或评论里输入一段script如果不做过滤直接存库再渲染到页面上浏览这段内容的其他人就会中招。我的处理方式是在后端入口统一转义用Spring Boot的过滤器或者写一个全局的字符串处理工具都可以关键是“不能信任前端传过来的任何内容”。Thymeleaf默认会转义th:text里的HTML标签但如果你用了th:utext就一定要非常小心。社区模块我全部用th:text输出宁可让用户输入的内容以纯文本呈现也不能让它变成可执行HTML。4.4 列表页时间格式化和分页社区发帖列表和评论列表都有时间字段数据库里存的是DATETIME在页面上直接显示会是“2025-01-15T10:30:00”这种中间带T的格式非常难看。我的做法是在实体类上用JsonFormat或者在getter里格式化。更推荐的做法是Thymeleaf模板中用内置的#temporals工具类th:block th:withcreateTime${#temporals.format(post.createTime, yyyy-MM-dd HH:mm)} span th:text${createTime}2025-01-15 10:30/span /th:block但如果你用了MyBatis-Plus的实体映射createTime字段类型是LocalDateTime此时要注意MySQL驱动版本和Java时间类型之间的兼容问题。比较省心的方案是直接在实体类上给字段加TableField(fill FieldFill.INSERT)配合MetaObjectHandler自动填充创建时间这样插入数据时时间字段不用手工传值。分页我用的也是MyBatis-Plus内置的分页插件。配置一个PaginationInnerInterceptor之后查询只需要PagePost page new Page(current, size); postMapper.selectPage(page, wrapper);即可。这里要提醒一句分页查询最好把排序条件写在wrapper.orderByDesc(Post::getCreateTime)里不要依赖数据库默认顺序否则分页后排序会乱掉。5. 从开发到交付环境配置、打包部署与演示视频录制我不想只把这篇文章写成代码讲解。真正让一个Spring Boot项目“跑起来给别人看”的环节其实藏着一堆细节。这一节我会完整地走一遍从环境准备到视频录制交付的全流程。5.1 环境准备清单一个干净的环境需要准备的东西如下JDK 8 或 JDK 11Spring Boot 2.x 搭配这两个版本最稳Maven 3.6MySQL 5.7 或 MySQL 8.0IDEIntelliJ IDEA 或 Eclipse一个带图形界面的浏览器演示用如果你是第一次跑这个项目我建议按顺序来做先装JDK并配好JAVA_HOME再装Maven并配置阿里云镜像不然下载依赖能等到你怀疑人生然后装MySQL并设置root密码最后导入项目。5.2 application.yml里的关键配置配置是Spring Boot项目里最容易出错的地方。我贴一份核心配置并解释每个字段为什么这么写server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/gufeng_website?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: yourpassword thymeleaf: cache: false encoding: UTF-8 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: autoserverTimezoneAsia/Shanghai这条必须加不加的话MySQL 8.0的驱动会报时区错误或者时间偏移8小时。characterEncodingutf8保证中文数据正常存取。thymeleaf.cache: false让改完模板刷新页面就能看到效果调试时必备部署上线时再改成true。5.3 打包成可执行JAR并运行搞清楚了代码接下来就是打包部署。直接在项目根目录执行mvn clean package -DskipTests等构建成功target目录下会生成一个gufeng-website-0.0.1-SNAPSHOT.jar。运行时只要java -jar gufeng-website-0.0.1-SNAPSHOT.jar然后浏览器访问http://localhost:8080就可以了。这里有一个我踩过很多次的坑如果用IDEA自带的打包功能要注意选择Maven方式打包而不是Artifacts方式。后者打出来的JAR经常缺失依赖导致java -jar跑起来报ClassNotFoundException。另外打包前务必确认application.yml里的数据库密码确实连接得上这是最常见的“打好了包跑不起来”的原因。5.4 演示视频和讲解视频应该怎么录这一节我要多说点因为“源码文档运行视频讲解视频”这四个交付物里视频质量往往是被忽视的。很多人的运行视频就是对着屏幕乱点一通五分钟过去了老师什么都没看清楚。我的运行视频录制脚本是固定的五步节奏第一步展示项目结构。在IDE里展开源码目录快速地逐层扫过controller、service、mapper、entity、config、resources让观看者知道代码是怎么组织的。第二步展示数据库。打开Navicat或命令行依次展开表手动查两条诗词数据说明数据来源和表关系。这一步很关键因为很多人关心“数据哪来的”你要在视频里展示一个已有数据的数据库。第三步启动项目。展示启动日志从Spring Boot Banner到Started Application in x seconds然后打开浏览器访问首页。第四步逐模块演示功能。顺序建议是游客浏览首页和诗词列表 → 用户注册登录 → 查看诗词详情 → 发表评论 → 点赞 → 发帖 → 后台登录 → 管理诗词。每个功能点切换前停顿两秒让观看者看清楚URL变化。第五步展示亮点。把你认为最好的功能重点演示比如诗词搜索、按朝代筛选、标签关联推荐。这是让老师记住你项目优势的机会。讲解视频则不同它的核心是代码逻辑而不是操作演示。我建议对照着Controller和Service层讲三个问题请求是怎么进来的、业务处理做了什么、数据是怎么流到页面上的。讲解时不要照着代码逐行念按下述三条主线串起来讲足够一条登录请求从浏览器到Controller到Service到Mapper再到数据库整个调用链路的职责划分。一个诗词详情页的数据组装过程基本信息、作者信息、标签、上一篇下一篇、相关推荐分别来自哪些方法。一个点赞请求如何保证幂等性以及数据库唯一约束在里面的作用。只要这三条线能讲明白讲解视频的深度已经超过大多数同类项目了。6. 复盘这套系统最常见的坑和我的处理方式最后这部分是纯经验。每个项目做完之后我都会把过程中踩到的坑记录下来。这套古风诗词网站也不例外下面五条是重复出现频率最高的你可以直接当作避坑清单用。6.1 中文乱码问题中文乱码的根源只有一个字符集不一致。MySQL数据库的默认字符集、JDBC连接串的characterEncoding、Thymeleaf模板的编码这三者必须统一为UTF-8。如果发现页面中文乱码先看数据库连接串有没有characterEncodingutf8再执行SHOW CREATE DATABASE确认数据库本身的字符集是utf8mb4最后检查thymeleaf视图解析的编码。大部分乱码问题都出在这三处之一。6.2 静态资源找不到Spring Boot默认静态资源路径是classpath:/static/。如果把CSS、JS、图片放到了src/main/webapp下打包成JAR后这些资源是访问不到的。我建议统一放在src/main/resources/static目录下Thymeleaf模板里引用时用th:href{/css/style.css}这样打包后也能正常工作。6.3 LocalDateTime带来的转换问题实体类用了LocalDateTime但MyBatis-Plus传给前端页面时如果格式没处理好页面上会出现一串“[object Object]”或乱七八糟的格式。我的做法是全局统一定义序列化格式在application.yml加如下配置spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai配合Thymeleaf端再格式化一遍双保险。如果是普通查询传到页面也可以在实体类字段上加JsonFormat(pattern yyyy-MM-dd HH:mm:ss)。6.4 修改和删除数据时的外键约束诗词表关联了作者表如果直接删除一个作者而他名下还有诗词数据库会产生某个诗词记录没有作者的情况页面上就会出现空指针或NullPointerException。我的建议是不让用户删除有内容关联的作者先在后台做一个提示“该作者名下还有N首诗词请先转移或删除这些诗词”。同理删除诗词时要考虑它关联的标签、点赞记录、评论记录。最省事的方式是用物理外键ON DELETE CASCADE但如果不想引入物理外键就一定要在删除代码里手动先删掉关联子表的数据否则会有孤儿数据甚至外键约束报错。6.5 启动类位置与包扫描Spring Boot的启动类必须放在根包下保证SpringBootApplication默认扫描到所有子包。如果启动类放错位置最典型的现象是明明写了Service、Mapper注解的类却一直报“找不到Bean”错误。检查方法很简单启动类所在的包应该是com.gufeng.website而Controller、Service、Mapper这些类都应该在它的子包里。这真是一个看起来很基础、但自己写项目时最容易犯的错。一旦遇到“No qualifying bean of type”这类错误第一反应不是去加注解而是先检查包结构。另外一个相关的坑是Mapper接口扫描。如果Mapper接口没有加Mapper注解或者启动类上没有MapperScan(com.gufeng.website.mapper)MyBatis-Plus就不会注册对应的Mapper Bean。我一般习惯在启动类上直接加MapperScan这样以后每新增一个Mapper接口都不用再单独打注解。说实话这套项目从难度上看并不算高但它覆盖的知识点非常完整Spring Boot的自动装配、Controller到Service到Mapper的调用链、MyBatis-Plus的条件构造器、Thymeleaf的模板渲染、权限拦截器、防重复点赞的数据建模思路、打包部署流程再加上文档和视频的交付规范认真啃下来对一个Java初学者来说足够学到一个完整的Web项目开发套路了。如果你拿到手是要做课设或毕设我的建议是不要只想“跑起来”而是把它当成一个真实的产品去理解。试着改一改需求比如加一个“诗词接龙”的玩法或者把点赞做成“点赞收藏”双维度再或者给后台加一个数据统计面板。当你发现自己能在这个基础上的任意加需求和改代码时那才算是真正把这套系统吃透了。
返回列表