最近有朋友发给我一条项目链接标题写的是“Java SpringBootVue3MyBatis 校园资料分享平台系统源码前后端分离MySQL数据库”。我第一反应是这又是一套非常典型的 Java 后端练手项目。看完描述再实际跑一遍发现这类系统虽然看起来只是课设水平但背后覆盖的技术点一点都不少SpringBoot 写业务接口、Vue3 做管理界面、MyBatis 操作 MySQL、JWT 管登录、接口做分页、文件做上传下载这些东西恰好是后端开发日常最常用的一整条链路。如果你正在准备毕业设计、课程设计或者想在简历上写一个“完整的前后端分离项目”这套东西确实够用。今天我就按实际从源码梳理到跑通的顺序把技术选型、表结构设计、后端接口、前端页面、部署联调这些环节里的关键细节全部拆开讲顺便把我在这个过程中踩过的坑也一起交代清楚争取让你少走弯路。1. 项目整体设计与技术选型1.1 这个系统到底在解决什么问题校园资料分享平台要处理的痛点其实很直白期末考试前想找往年试卷通常得在班级群、QQ群、网盘链接里翻半天找到一个好课件想分享给同学又找不到统一入口。所以这类平台天然适合用“分类上传 检索下载 用户管理”来概括。业务不复杂但五脏俱全刚好能把前后端开发的基本功全部串起来。从业务流转看核心链路就是用户注册登录 - 浏览分类和检索资料 - 上传自己的资料 - 管理员审核或直接发布 - 其他用户下载。这个流程里既涉及权限控制又涉及文件存储、列表分页、数量统计每一处都能展开成真实的工程问题。跟那种纯“教学 Demo”不同这套系统是有完整业务闭环的做完以后你对“用户从点击到拿到文件”的整个过程会形成完整的认知。1.2 四个核心组件各管什么技术栈是标题里写死的SpringBoot Vue3 MyBatis MySQL前后端分离。实际拆开看这四个组件各司其职搭配很合理。组件角色在这个项目里干什么SpringBoot后端服务框架提供 RESTful 接口处理业务逻辑、鉴权、文件读写Vue3前端框架渲染页面、管理路由和交互状态调用后端接口MyBatis数据访问层把 SQL 写在 Mapper 中灵活控制数据库操作MySQL数据存储保存用户、资料、分类、下载记录等所有业务数据我为什么觉得这套组合很适合练手SpringBoot 省去了大量 XML 配置内嵌 Tomcat写一个可运行的后端服务成本很低MyBatis 相比 JPA 更强调 SQL 可控性你很清楚每条查询干了什么排查问题也不至于隔着一层抽象Vue3 的组合式 API 在组件逻辑整理上比 Vue2 的 options API 舒服不少配合 Vite 开发体验也快。前后端分离还带来的一个额外好处是部署灵活前端可以单独丢 Nginx后端可以独立跑 jar这正好符合当前主流团队的协作模式。1.3 技术选型里的几个取舍点需要说实话这类项目有很多变体比如把 MyBatis 换成 MyBatis-Plus把 Vue3 换成 React或者把本地文件存储换成对象存储。项目标题既然明确写了原生 MyBatis那我们就专注在这套技术语义里展开。MyBatis 的价值在于动态 SQL 和分页插件这也是标题里热搜词提到的重点后面我会专门讲。至于为什么不推荐用简单的 JdbcTemplate因为它的结果映射和动态条件处理太手动了资料列表这种多条件查询会写到你怀疑人生。同样用 JPA 虽然也能实现但很多同学在联调阶段会因为自动生成的 SQL 不达预期而陷入排查困境不如 MyBatis 一清二楚。还有一个经常被忽略的点项目里尽量保留角色概念普通用户和管理员。很多校园项目不做审核用户上传资料后直接发布结果平台上全是垃圾文件和重复内容。加上“待审核 - 已上架 - 已下架”的状态流转虽然只是多一个字段但它是答辩和面试里很加分的业务细节。后面我在表结构里会详细展开这个字段的设计。2. 数据库设计与核心表结构2.1 核心表设计与字段取舍数据库设计是这类项目最容易糊弄、也最容易被面试官追问的部分。我先给出一套足够支撑业务的最小核心表一共五张用户表、分类表、资料信息表、下载记录表、公告表。用户表 user 的核心字段是id、username、password、nickname、role、status、avatar、create_time。username 必须唯一password 永远不要明文存储至少用 BCrypt 加密role 用数字区分普通用户和管理员比字符串更省空间也更好判断status 用来控制账号是否可用这是后话操作的基础。分类表 category 建议保留 parent_id哪怕现在只有一级分类也要为以后扩展二级分类留好余地。字段就是 id、parent_id、name、sort。sort 字段控制前端展示顺序避免以后每条记录都要改代码。资料表 resource 是核心表字段包括 id、category_id、title、summary、file_path、file_size、file_type、download_count、uploader_id、status、create_time、update_time。这里面有几个字段取舍值得细说。file_size 我强烈建议你用 bigint 而不是 int因为资料文件很可能超过 2GBint 的最大值约 21 亿字节换算下来刚过 2GB存视频课件很容易溢出summary 用 text 而不是 varchar(255)资料简介几百字很正常download_count 是个典型的冗余字段每次下载直接加 1比统计下载记录表 count(*) 高效得多。status 用 tinyint0 表示待审核1 表示已上架2 表示已下架这个状态字段是内容管理的基础。下载记录表 download_record 用来记录谁在什么时间下载了什么文件字段是 id、resource_id、user_id、create_time。如果设计成“每个用户对同一份资料只能下载一次重复下载不计数”那就要在 resource_id 和 user_id 上加联合唯一索引同时下载接口里先查记录再决定是否插入新纪录、是否更新 download_count。公告表 notice 就简单了title、content、create_time 三个字段足够。2.2 字段类型和字符集的几个隐藏问题表结构里还有一个大多数人会忽略的点字符集。建库时指定 CHARSETutf8mb4而不是 utf8。因为 utf8 在 MySQL 里最多只能存 3 个字节的字符一些特殊符号和 emoji 会报错或者变成乱码学生资料标题里偶尔就会出现这类字符。时间字段建议统一用 datetimeJava 后端用 LocalDateTime 来对应前端通过 Jackson 配置统一格式化成 yyyy-MM-dd HH:mm:ss否则序列化出来是一串难读的数组格式。另一个设计建议是“逻辑外键优先不用物理外键”。很多教材喜欢强调外键约束但真实项目里物理外键会影响插入性能级联删除还可能带来误删风险。保留 category_id、uploader_id 这样的逻辑关联字段事务和业务代码控制数据一致性是目前更主流的做法。面试官问你为什么不建外键你能答出这个理由比背概念强很多。2.3 建表 SQL 和索引建议这里给出一份可直接照用的核心建表 SQL覆盖用户表和资料表其余表按相同规范扩展create table user ( id bigint primary key auto_increment, username varchar(50) not null unique, password varchar(100) not null, nickname varchar(50), role tinyint default 0 comment 0-普通用户 1-管理员, status tinyint default 1 comment 0-禁用 1-正常, avatar varchar(255), create_time datetime default current_timestamp ) engine InnoDB default charset utf8mb4; create table resource ( id bigint primary key auto_increment, category_id bigint not null, title varchar(200) not null, summary text, file_path varchar(255) not null, file_size bigint default 0, file_type varchar(50), download_count int default 0, uploader_id bigint not null, status tinyint default 0 comment 0-待审核 1-已上架 2-已下架, create_time datetime default current_timestamp, update_time datetime default current_timestamp on update current_timestamp, key idx_category (category_id), key idx_uploader (uploader_id), key idx_create_time (create_time) ) engine InnoDB default charset utf8mb4;索引方面resource 表的 category_id 和 uploader_id 是第一批必加索引创建时间排序在列表页很常见也加上。title 的模糊搜索在数据量大时没法走普通索引like %关键词% 会全表扫但校园项目初期数据量不大暂时可行。以后如果资料量涨起来再考虑全文索引或者接入 Elasticsearch现在不用过度设计。还有一个容易被忽略的操作细节库表字段都设计成小写加下划线风格Java 实体类统一用驼峰命名在 MyBatis 里开启 mapUnderscoreToCamelCasetrue就不用手动给每字段写 resultMap 映射。这个配置能让你少写几百行重复代码。3. 后端核心模块落地3.1 统一返回结构与全局异常处理前后端分离之后接口返回格式必须统一否则前端每个请求都要单独解析维护成本极高。我习惯定义一个 Result 泛型类固定三个字段code、message、data。成功时 code200业务失败时 code比如 500 或 400前端只看 code 就能判断不用关心 HTTP 状态码。这个类的静态方法 success(T data) 和 fail(String message) 可以在所有接口里复用。光有统一返回还不够还需要一个全局异常处理器。在 SpringBoot 里加一个类标上 RestControllerAdvice然后用 ExceptionHandler 捕获业务异常和参数校验异常。这样做的好处是业务代码里不需要到处 try-catch你只需要在真正需要中断流程的地方抛出异常由全局处理器统一转成 Result.fail 返回。比如上传资料时文件为空直接 throw new BusinessException(文件不能为空)前端接收到的就是标准错误结构体验一致。3.2 JWT 登录鉴权与请求拦截登录鉴权这块我强烈建议用 JWT 而不是 Session。原因很简单前后端分离后后端可能是多个实例部署Session 如果要共享还得引入 Redis而 JWT 是无状态的服务端不保存会话请求头里带上 token 就能解析出用户身份。流程拆开看是这样用户提交 username 和 password后端先查 user 表用 BCrypt.matches 校验密码比对通过后用用户的 id、username、role 生成 token设置过期时间比如 24 小时。前端登录成功把 token 存进 localStorage后续请求在 axios 拦截器里自动加上 Authorization: Bearer token。后端写一个 OncePerRequestFilter每次请求进来先解析 token拿到当前用户信息放进共享上下文接口里直接取当前用户不需要每次都重新查数据库。这里必须提醒几个实际踩过的坑token 密钥不能写死在代码里放到 application.yml 配置文件中以后部署到服务器直接改配置就行JWT 的过期时间不要太短否则用户刷着页面突然就退出登录了体验很差前端路由也要配合做守卫没有 token 时让用户跳转到登录页不能等到接口报 401 再处理。另外 JWT 无法主动失效如果管理员想踢人下线只能等 token 过期在校园项目里这是可以接受的代价。3.3 文件上传与下载最容易踩坑的部分资料分享平台最核心的操作就是上传和下载。后端上传接口接收 MultipartFile但这里有几个关键细节。第一文件名必须重命名我习惯用 UUID 拼接原始扩展名避免用户传了两个同名文件互相覆盖第二文件要保存到约定的磁盘目录比如项目配置里的 upload.dir然后把相对路径记录到 resource.file_path不要把上传文件的绝对路径也写进数据库否则迁移服务器时会很痛苦第三上传大小限制要主动调大SpringBoot 默认最大上传文件只有 1MB传一个 PDF 课件都会失败你需要设置 spring.servlet.multipart.max-file-size200MB 和 max-request-size210MB。下载接口就更需要讲究了。根据资源 id 查出 file_path从磁盘读取文件然后通过 ResponseEntity 返回二进制流同时设置 Content-Disposition 响应头让浏览器弹出下载框而不是直接打开预览。这个头里中文文件名要特殊处理用 URLEncoder.encode 编码后拼成 attachment; filename*UTF-8xxx我实测过不这样设置的话中文文件名下载后大概率变成乱码。下载成功后别忘了做两件事download_count 加 1插入 download_record 记录。这两步最好放在同一个事务方法里避免文件下载了但计数没更新。关于存储位置本地磁盘对这个项目来说足够。但如果部署在生产环境多实例情况下每台服务器磁盘不一致文件存在哪台机器是个大问题。这块后期可以换成 OSS 或 MinIO属于很自然的扩展方向。3.4 MyBatis 分页和多条件查询资料列表页是典型的多条件分页查询搜索条件包括分类、关键词、状态。用原生 MyBatis 时我推荐用 PageHelper 分页插件这也是 MyBatis 生态里最常用的分页方案。用法其实只有两步查询前调用 PageHelper.startPage(pageNum, pageSize)查询后把结果包成 PageInfo 返回给前端。PageInfo 里自带总条数、总页数、当前页这些字段前端直接绑定就行。这里有一个很多人不知道的坑PageHelper 的原理是 ThreadLocal 存储分页参数再通过拦截器对最近的一条 SQL 自动拼接 limit所以 startPage 之后必须紧跟你要分页的那条查询语句中间不能穿插其他查询否则分页参数会被别的 SQL 吃掉数据会出现可怕的错乱。我写过一次两个查询夹在一起的代码结果列表页出来全是重复数据排查了很久才发现是分页串了。多条件查询用动态 SQL 解决核心是 MyBatis 的 where 和 if 标签。举个例子查询资料列表时分类 id 非空就加上 category_id 等值过滤关键词非空就加 title like 模糊匹配状态固定为已上架。这些条件拼起来如果不小心最容易出问题的地方是“where 后面多了 and”或者“每个条件都要加 11 占位”用 where 标签会自动去掉开头的 and比手动拼接 SQL 安全得多。还有模糊匹配要用 concat(%, #{keyword}, %)不要直接写成 %${keyword}%后者会导致 SQL 注入这是老生常谈但永远有人踩。4. 前端 Vue3 页面实现与联调4.1 从 Vite 初始化到目录划分前端我用 Vite 创建 Vue3 工程命令是 npm create vitelatest frontend -- --template vue。相比 WebpackVite 基于 ESBuild 预构建依赖冷启动速度快很多开发体验顺滑这也是 Vue3 官方推荐的方式。工程创建后我不喜欢把代码全堆在 App.vue 里更建议把目录按职责分开src/api 放接口请求封装src/router 放路由配置src/views 放页面组件src/components 放可复用组件src/utils 放工具函数。这样划分以后每个页面只需要关注自己的业务逻辑接口请求都在 api 目录下统一管理以后改接口地址或者请求参数也只需要在一个地方操作。4.2 Axios 的封装思路前后端分离项目里axios 封装是必须做的一步。如果每个页面都直接写 axios.get一旦要统一加 token 或者统一处理错误就要全局搜索替换非常痛苦。我封装的方式是创建一个 request.js核心是两个拦截器。请求拦截器里从 localStorage 拿 token有就在 config.headers 里加上 Authorization: Bearer token。响应拦截器里先判断 res.data.code 是否等于 200等于的话直接返回 res.data.data页面里拿到的直接是业务数据不用每个组件里再解一层不等于 200 或者网络异常就统一弹 ElMessage 提示错误信息同时如果是 401 就清空 token 并跳转登录页。这样封装完业务页面代码会非常干净调用一个接口就两行引入 api 函数await 拿到数据塞进响应式变量。4.3 资料列表页和分页状态设计资料列表页是前端工作量最大的页面。页面结构基本是顶部搜索区分类下拉、关键词输入框、搜索按钮中间内容区资料卡片或表格列表底部固定分页组件。我用 reactive 定义一个 searchForm包含 categoryId、keyword、pageNum、pageSize 四个字段然后写一个 fetchList 函数读取当前搜索条件请求接口。这里有两个细节容易出错第一搜索按钮点击时要把 pageNum 重置为 1否则用户在第 10 页搜索结果可能直接跳到原来页码导致空白或越界第二分页组件里 pageNum 和 pageSize 的绑定名称必须和后端参数一致用 el-pagination 的 v-model:current-page 和 v-model:page-size事件里重新触发 fetchList这样整个分页状态才闭环。列表展示时建议用分页接口返回的 total 驱动分页组件的 total 属性这样不仅分页准确也方便后端后续加缓存或统计功能。每个资料卡片上至少展示标题、分类名、上传者、文件大小、下载次数和上传时间上传者昵称和分类名是通过联表查出来的这也是多表查询的意义所在。4.4 联调过程里几个高危细节本地联调时第一个绕不开的问题是跨域。我实践下来最稳的方案是在 Vite 的 vite.config.ts 里配置代理把所有以 /api 开头的请求转发到 http://localhost:8080这样浏览器看来所有请求都指向同一个前端域名压根不会触发跨域。不建议开发阶段在后端到处加 CrossOrigin虽然能临时跑通但生产环境经过 Nginx 转发后很容易出现配置不一致而且后端接口直接暴露也不是好习惯。第二个容易翻车的地方是 Long 类型精度丢失。Java 后端如果接了雪花 ID 或者未来数据量变大Long 序列化成 JSON 传给前端JavaScript 的 Number 超过 2^53 就会丢精度。这个校园项目用自增主键暂时不触发但如果你把 ID 换成雪花 ID就要给 Long 字段加注解序列化成字符串。提前做这个处理面试时聊到分布式 ID 会更有底气。第三个是日期格式。后端 LocalDateTime 默认序列化格式是类似“2024-06-01T10:30:00”的 ISO 格式前端显示很难看。在 application.yml 里配置 jackson.date-formatyyyy-MM-dd HH:mm:ss 和 time-zoneGMT8全局输出统一格式省掉前端到处写格式化函数。还有一个上传接口的细节axios 发送 FormData 时不要手动设置 Content-Type 为 multipart/form-data要让它自动带 boundary否则后端解析 MultipartFile 会失败。这个坑我印象特别深前后端联调时上传总报空指针查了半天才发现是请求头被手动写死导致参数没法解析。5. 环境搭建、部署与常见问题排查5.1 本地环境的版本组合这套项目推荐本地装 JDK 8 或 JDK 11、Maven 3.6、MySQL 5.7 或 8.0前端用 Node.js 16 和 npm。MySQL 建议直接用 8.0毕竟老版本迟早要淘汰。这里特别提醒一个 MySQL 8.0 的驱动问题JDBC URL 里驱动类要写 com.mysql.cj.jdbc.Driver同时加上 serverTimezoneAsia/Shanghai、useUnicodetrue、characterEncodingutf8、useSSLfalse、allowPublicKeyRetrievaltrue 这几个参数。如果不加 allowPublicKeyRetrieval新版 MySQL 8 默认的 caching_sha2_password 认证会直接报 Public Key Retrieval is not allowed很多人第一次启动就被这个卡住。5.2 从源码到跑通的启动顺序我在一个新的环境里跑通这套项目一般按下面这个顺序能少踩很多坑先建库执行 create database campus_resource default character set utf8mb4 collate utf8mb4_general_ci保证字符集没问题。导入项目自带的 SQL 脚本初始化表结构和测试数据。修改后端 application.yml 里的数据库地址、账号、密码确认前面提到的 JDBC 参数都在。终端执行 mvn spring-boot:run看到 Started Application 字样就说明后端起来了。如果用的 IDEA注意确保 resources 目录里的 yml 被正确编译有时候配置文件没进 target 目录会导致启动时找不到数据源。进入 frontend 目录执行 npm install安装依赖时如果报权限错误多半是 Node 版本太高或太低切换到 16 或 18 的 LTS 版本再试。执行 npm run dev访问 http://localhost:5173登录页面出来就算前后端连通了。访问后会调登录接口这时候 Vite 代理会把请求转发到后端接口通了就能正常登录。5.3 常见问题速查表我把实操中高频出现的问题整理成一张速查表方便你对照排查。问题现象可能原因解决办法数据库连接报 Public Key Retrieval is not allowedMySQL 8 认证方式问题JDBC url 加 allowPublicKeyRetrievaltrueuseSSLfalse后端启动失败提示 Access denied for user数据库账号密码或权限不对用 root 账号确认密码或执行 grant 授权8080 端口被占用之前进程未退出或其他程序占用改 server.port或 kill 对应进程前端请求 /api 接口 404Vite 代理没配置或配置错误检查 vite.config.ts 的 proxy 配置并重启前端上传大文件失败SpringBoot 默认上传上限 1MB调大 spring.servlet.multipart.max-file-size下载文件名中文乱码Content-Disposition 编码问题按 UTF-8 URLEncoder 编码并设置 filename*前端刷新页面后 404history 路由没有服务端回退Nginx 加 try_files 或路由改 hash 模式列表接口返回很慢大字段未建索引或分页失效检查 where 条件字段索引确认分页参数正确这中间我要重点说一个问题很多项目跑不起来不是因为代码有问题而是数据库环境不一致。你自己本地装 MySQL 8.0 没问题但你拷给同学的时候对方可能是 5.7SQL 脚本里如果有 8.0 新增的语法就会直接报错。所以初始化脚本尽量保持兼容或者明确标注使用的 MySQL 版本别让环境问题干扰代码本身。部署到服务器时后端的 jar 包用 mvn package -DskipTests 打包前端用 npm run build 生成 dist 目录然后丢到 Nginx 的 html 目录下再加一条反向代理规则把 /api 转发到后端监听端口。常见的“本地能跑服务器连不上数据库”基本是云服务器安全组没放行 3306 端口或者 MySQL 的 bind-address 只绑定了 127.0.0.1。跑完这套系统我最大感受是真正拉开差距的地方不在 CRUD 本身而在于联调过程中冒出来的大量细节。比如时间格式怎么统一、文件下载文件名怎么处理、分页参数在哪一层失效、无状态登录怎么做这些才是面试官判断你有没有亲手做过项目的关键。如果时间充裕我建议顺手做两个扩展一是给热点资料加 Redis 缓存二是用 MinIO 替换本地文件存储这两个方向也是这套系统最自然的演进路线。别急着堆功能先保证整条链路能完整跑通再考虑旁的。项目是别人写的跑起来之后那些 bug 才是真正属于你的学习材料。
企业数字化 ERP 产品动态
相关推荐
HOOPS Envision CAE数据分析与可视化工具包 CAE数据分析与可视化工具包
HOOPS Envision 是一款集 CAE 数据导入、分析、可视化、报告和自动化于一体的工具包。这款经过市场验证的 SDK 为桌面和原生 Web 应用程序提供高性能的分析工具和高效的共享工作流程。适用于桌面和网页
CAE 数据分析与可视化工具包
25 年来ÿ… · 2026/9/26 7:57:24
Unity Mesh内存优化:Read/Write开关与内存泄漏排查实战 1. 从一次线上事故说起:Mesh内存为什么会失控 去年我们团队做的一个开放世界手游项目,在低端机上频繁出现闪退,崩溃日志指向 GfxDevice::DeallocateMesh 和 MemoryManager::Allocate 的失败。排查了整整三天,最后定位到一个看… · 2026/9/26 7:57:18
SpringBoot+Vue3校园资料分享平台:前后端分离完整实战源码解析 做校园资料分享这块,最头疼的往往不是某个技术点有多难,而是一堆细碎的东西凑在一起后互相打架。文件上传、分类检索、积分扣减、权限校验、前后台联调,每一个单拎出来都不算新东西,但要把它们捏合成一个能真正跑起来、学生愿意用… · 2026/9/26 7:57:18
从VSCode到Cursor:我的AI编程真实体验与效率变革 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 9:45:48
智能电视点播困局破解:堡盒TV内置源与本地多仓深度解析 智能电视用久了,最让人头疼的不是硬件老化,而是内容生态的割裂。我手上这台小米电视买了三年,系统自带的应用商店里能装的正经点播软件越来越少,好不容易找到几个能用的,不是广告多到离谱,就是资源库更新慢… · 2026/9/26 9:45:48
Win10无法播放MP4?HEVC视频扩展安装与硬解软解全攻略 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 9:45:42
Omarchy:GNOME原生平铺的Wayland发行版深度解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 9:45:42
VisualVM实战指南:JDK版本匹配、远程连接与深度诊断 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 9:45:42
GPIO引脚不够用?用Charlieplexing算法驱动LED点阵的完整指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 9:45:42
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46