简介:这是一套面向Java全栈学习者与个人知识管理需求者的完整项目源码,基于Spring Boot与Vue构建,适合作为毕业设计、课程设计或全栈练手参考。项目围绕个人知识库场景,实现文档与电子书的增删改查、内容编辑、点赞统计、快照生成,以及分类的增删改查与排序管理,并配套用户登录注销、权限控制与日志记录等基础能力,前后端分离结构清晰。压缩包共138个文件,约672KB,其中78个Java文件承载后端业务逻辑,13个XML与3个properties、2个yml负责配置与持久层映射,11个Vue组件与5个TypeScript、4个JavaScript文件构成前端界面与交互,另有SQL脚本、HTTP接口测试文件及构建脚本辅助开发调试。目前已有71人学习下载,可帮助读者快速理解知识管理系统的模块划分、接口设计与前后端协作方式,并在此基础上二次开发或扩展功能。
1. 从一份 Spring Boot + Vue 知识管理系统源码说起:它到底能解决什么
很多人做个人知识管理,第一反应是找现成的笔记软件,但用久了总会撞到天花板——数据不在自己手里、想加个标签体系得看厂商脸色、导出格式还锁死。这份基于 Spring Boot 和 Vue 的个人知识管理系统源码,走的是另一条路:把整套前后端工程交到你手上,数据库表、接口、页面全都能改。它适合两类人,一类是想拿它当脚手架快速搭出自己知识库的后端开发者,另一类是想通过一个完整项目把 Spring Boot 和 Vue 串起来练手的学生或转行者。源码包里前后端分离,后端负责笔记、分类、标签、用户这些核心数据的增删改查,前端负责把这些数据渲染成可交互的页面。你拿到手之后,改改配置就能跑起来,想加全文检索、想接对象存储、想换 UI 主题,都有地方下手。下面我按实际拆包和跑通的顺序,把这份资源从环境到部署讲透。
2. 环境准备与工程结构:把 Spring Boot 和 Vue 的依赖先理顺
2.1 后端 Spring Boot 工程的依赖与配置
拿到源码先别急着点运行,第一件事是看后端pom.xml里的 Spring Boot 版本和 JDK 要求。常见做法是打开pom.xml,确认<parent>里的spring-boot-starter-parent版本,再对照本机 JDK。如果版本是 2.7.x 或 3.x,JDK 至少 8 或 17,别拿 JDK 8 去跑 Spring Boot 3 的工程,启动直接报Unsupported class file major version。数据库方面,这类知识管理系统一般用 MySQL,配置文件在src/main/resources/application.yml或application.properties。我一般会先把数据源、端口、MyBatis 的 mapper 路径这三处改掉,再执行建表脚本。
# application.yml 关键配置片段 server: port: 8080 # 后端服务端口,和前端代理对应 spring: datasource: url: jdbc:mysql://localhost:3306/knowledge_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml # XML 映射文件位置 type-aliases-package: com.example.entity # 实体类包名这段配置里,server.port决定后端监听端口,前端开发时的代理要指向同一个端口。url里的serverTimezone必须写对,否则插入时间字段会差 8 小时,这是血泪经验。mapper-locations如果写错,启动时报Invalid bound statement,说明 MyBatis 没找到 XML。type-aliases-package影响 XML 里能不能用短类名,写错会提示类找不到。改完配置,先跑一次mvn clean compile,编译过了再启动,能省掉很多排查时间。
2.2 前端 Vue 工程的安装与代理配置
前端目录一般叫vue-frontend或web,进去先看package.json里的依赖和脚本。Vue 2 和 Vue 3 的安装命令不一样,Vue 2 用npm install基本能过,Vue 3 如果遇到node-sass编译失败,换成sass就行。安装依赖这一步最容易翻车的是 Node 版本,Node 16 和 Node 18 对某些老依赖的兼容性不同,我一般先用nvm切到项目README里写的版本,没写就试 Node 16。
# 进入前端目录后执行 npm install # 安装依赖,失败先看 node 版本 npm run serve # Vue CLI 项目启动开发服务器 # 如果是 Vite 项目则用 npm run dev启动之后,前端默认跑在 8081 或 5173,但后端在 8080,浏览器直接请求会跨域。解决办法是在vue.config.js或vite.config.js里配代理,把/api开头的请求转发到后端。
// vue.config.js 代理配置 module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', // 后端地址 changeOrigin: true, pathRewrite: { '^/api': '' } // 去掉前缀,按后端实际路径调整 } } } }target必须和后端server.port一致,pathRewrite要看后端接口有没有统一前缀。如果后端接口本身就是/api/note/list,那就不需要重写;如果后端是/note/list,前端请求写/api/note/list,就得把/api去掉。这一步配错,页面能打开但所有数据接口 404,控制台一片红。配完代理重启前端,登录页能正常请求验证码或登录接口,说明前后端已经通了。
2.3 数据库建表与初始数据导入
源码里通常带一个sql目录,里面是建表语句和初始数据。常见做法是先在 MySQL 里建一个空库,字符集选utf8mb4,排序规则utf8mb4_general_ci,然后用命令行导入。
# 创建数据库并导入 mysql -u root -p -e "CREATE DATABASE knowledge_db DEFAULT CHARACTER SET utf8mb4;" mysql -u root -p knowledge_db < sql/init.sql导入之后用SHOW TABLES;确认表都建好了,重点看用户表、笔记表、分类表、标签表这四张。如果导入报Unknown collation,说明 SQL 文件里的排序规则和你本机 MySQL 版本不匹配,把utf8mb4_0900_ai_ci改成utf8mb4_general_ci再导。初始数据里一般有一个默认管理员账号,密码可能是加密后的,登录不上就去看用户表里的password字段,或者找源码里的密码加密工具类重新生成一个。这一步做完,后端启动、前端启动、数据库有数据,三端就算齐了。
3. 核心功能模块拆解:笔记、分类、标签是怎么串起来的
3.1 笔记模块的增删改查与分页实现
知识管理系统的核心是笔记,后端一般用 MyBatis 或 MyBatis-Plus 做持久层。先看 Controller 层,找到NoteController,里面会有list、add、update、delete、detail这几个方法。分页通常用 PageHelper 或 MyBatis-Plus 的分页插件,前端传pageNum和pageSize,后端返回total和records。
// NoteController 分页查询示例 @GetMapping("/list") public Result list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(required = false) String keyword) { PageHelper.startPage(pageNum, pageSize); // 开启分页 List<Note> notes = noteService.findByKeyword(keyword); // 按关键词查 PageInfo<Note> pageInfo = new PageInfo<>(notes); // 包装分页信息 return Result.success(pageInfo); }pageNum和pageSize由前端传,默认值保证不传也能查。keyword是可选的搜索条件,对应前端搜索框。PageHelper.startPage必须紧挨着查询语句,中间不能插别的数据库操作,否则分页会乱。返回的PageInfo里包含total、list、pageNum等字段,前端表格组件直接绑定就行。如果分页不生效,先检查有没有引入 PageHelper 依赖,再看startPage后面是不是跟了别的查询。
3.2 分类与标签的多对多关系处理
笔记和分类一般是一对多,笔记和标签是多对多。多对多需要一张中间表,比如note_tag,存note_id和tag_id。后端在新增笔记时,先插入笔记主表,拿到自增 ID,再批量插入标签关联。
// 新增笔记时处理标签关联 @Transactional public void addNote(Note note, List<Long> tagIds) { noteMapper.insert(note); // 插入笔记,回填 ID if (tagIds != null && !tagIds.isEmpty()) { noteTagMapper.batchInsert(note.getId(), tagIds); // 批量插关联 } }@Transactional保证笔记和标签关联要么都成功,要么都回滚。noteMapper.insert之后,MyBatis 会把自增主键回填到note对象里,所以后面能直接用note.getId()。batchInsert一般用<foreach>拼 SQL,注意标签数量多的时候别拼太长,超过几千个要分批。查询笔记详情时,再根据note_id去中间表查标签,或者用一条 JOIN 语句直接带出来。前端展示标签用v-for渲染,点击标签跳转到按标签筛选的列表页。
3.3 前端路由与页面组件的对应关系
Vue 前端一般用vue-router管理页面跳转,路由文件在src/router/index.js。笔记列表、笔记详情、笔记编辑、分类管理、标签管理各对应一个组件。动态路由这块,如果详情页路径是/note/:id,组件里用this.$route.params.id拿笔记 ID。
// router/index.js 路由配置 const routes = [ { path: '/note/list', component: () => import('@/views/NoteList.vue') }, { path: '/note/detail/:id', component: () => import('@/views/NoteDetail.vue') }, { path: '/note/edit/:id?', component: () => import('@/views/NoteEdit.vue') }, { path: '/category', component: () => import('@/views/Category.vue') } ]/note/edit/:id?里的?表示 id 可选,新增时不带 id,编辑时带 id,同一个组件复用。import用懒加载,打包时按路由分割,首屏更快。如果路由跳转后页面空白,先看控制台有没有Failed to resolve component,一般是组件路径写错或文件名大小写不一致。前端调接口统一封装在src/api目录,用 axios 实例配baseURL和拦截器,token 过期统一跳登录页。
4. 避坑与常见问题排查:这些坑我替你踩过了
4.1 后端启动报数据库连接失败
现象是启动日志里出现Communications link failure或Access denied for user。原因通常是 MySQL 没启动、端口不对、用户名密码错,或者application.yml里的url少写了serverTimezone。解决步骤:先用mysql -u root -p在命令行能登进去,确认 MySQL 正常;再核对url里的端口是不是 3306,数据库名是不是和建库时一致;最后检查密码有没有被 Spring Boot 的占位符覆盖,比如${MYSQL_PASSWORD}环境变量没设。改完配置重启,看到Started Application in x seconds才算过。
4.2 前端 npm install 卡住或报 node-sass 错误
现象是npm install跑很久不动,或者报Node Sass could not find a binding。原因是node-sass对 Node 版本极其敏感,Node 16 以上基本装不上老版本。解决办法是先把package.json里的node-sass换成sass,再把sass-loader升到兼容版本,然后删掉node_modules和package-lock.json重新装。如果公司网络慢,配一下 npm 镜像能快很多。装完用npm run serve启动,编译报错先看是不是某个组件里用了未定义的变量。
4.3 接口 404 或跨域被拦截
现象是前端页面能打开,但登录或列表接口返回 404,或者浏览器控制台报CORS policy。原因是代理没配、pathRewrite写错,或者后端没加跨域配置。先看浏览器 Network 里请求的完整 URL,如果是http://localhost:8081/api/xxx返回 404,说明代理没生效,检查vue.config.js改完有没有重启。如果请求根本没发出去就报 CORS,说明代理没匹配上,把'/api'改成'/'试试。后端也可以加@CrossOrigin或全局跨域配置,但生产环境建议用 Nginx 统一转发,别在代码里放开所有来源。
4.4 分页查询返回全部数据
现象是前端传了pageSize=10,但接口返回了几百条。原因是PageHelper.startPage没生效,常见于用了 MyBatis-Plus 的分页插件但没配PaginationInnerInterceptor,或者startPage后面跟了别的查询导致线程变量被消费。解决方法是确认分页插件已注册,startPage紧挨着目标查询,中间不要插count或其他select。如果用的是 MyBatis-Plus,检查MybatisPlusConfig里有没有加拦截器。
4.5 打包部署后刷新页面 404
现象是npm run build之后把dist丢给 Nginx,首页能开,但刷新/note/detail/1就 404。原因是 Vue 是单页应用,路由由前端接管,Nginx 找不到对应文件。解决办法是在 Nginx 配置里加try_files $uri $uri/ /index.html;,把所有找不到的路径都指回index.html。后端打包成 jar 后,用java -jar xxx.jar启动,注意生产环境的数据库密码别写死在application.yml里,用启动参数或环境变量传进去。
5. 进阶用法:把知识管理系统改成你自己的检索工具
跑通之后,这份源码最大的价值是能按你的习惯改。我一般会先加一个全文检索,MySQL 的LIKE '%keyword%'数据量大了就慢,换成 Elasticsearch 或者 SQLite 的 FTS 都行。如果不想引入新组件,至少给笔记的title和content字段加联合索引,查询时用MATCH ... AGAINST或者把关键词拆成标签。另一个实用改动是接对象存储,笔记里的图片现在可能是存本地路径,部署到服务器后路径就失效,改成上传到 MinIO 或云厂商的对象存储,数据库只存 URL。
验证改动有没有效,我习惯用 Postman 先跑一遍接口,确认返回结构没变,再切到前端看页面。比如加全文检索,先在后端写一个/api/note/search?q=xxx,用 Postman 测关键词命中,再在前端搜索框绑这个接口。如果搜索没结果,先看数据库里有没有匹配的数据,再看 SQL 的LIKE有没有拼错,最后看前端传的参数名对不对。还有一个技巧是把常用查询做成EXPLAIN分析,看有没有走索引,type是ALL就说明全表扫描,得加索引或改查询条件。
从那以后我每次拿到一份前后端分离的源码,都强制先跑通「后端启动 → 数据库导入 → 前端代理 → 登录接口」这条最小链路,再动任何业务代码。这份 Spring Boot + Vue 的个人知识管理系统源码,结构清晰、依赖常规,适合拿来练手或者直接改成自己的知识库。希望帮到你。
本文还有配套的精品资源,点击获取