final-vibevault-tests/REPORT.md

51 lines
4.1 KiB
Markdown
Raw Normal View History

# 后端开发反思报告
---
## 1. 我遇到的最大挑战
在开发过程中,我遇到的最大挑战是 **JPA 实体类的双向关联维护**问题。
起初,我在实现 `Playlist``Song` 的一对多关系时,只是简单地在 `Playlist` 类中添加了 `@OneToMany` 注解,以为这样就完成了。但当我运行测试时,发现添加歌曲到歌单后,歌曲的 `playlist` 字段始终是 `null`,导致测试失败。
我尝试了多种方法排查:首先检查了注解是否正确,发现 `mappedBy` 属性设置没问题;然后在数据库控制台查看数据,发现 `songs` 表中的 `playlist_id` 确实是空的。这让我意识到问题出在双向关联的维护上。
经过查阅 JPA 文档,我终于明白了:在双向关联中,**关系的维护方是"多"的一方**(即 `Song`),而 `Playlist` 只是被动方。因此,仅仅调用 `songs.add(song)` 是不够的,还必须同时调用 `song.setPlaylist(this)` 来维护另一端的引用。最终的实现是:
```java
public void addSong(Song song) {
songs.add(song);
song.setPlaylist(this); // 关键:维护双向关联
}
```
这个问题让我深刻理解了 **ORM 框架只是工具,底层的关系型数据库原理仍然需要掌握**。双向关联看似方便,但如果不理解其工作机制,反而会成为 bug 的温床。
---
## 2. 如果重新做一遍
回顾这次开发,有几个地方我觉得可以做得更好:
**首先是异常处理的设计**。目前 `ResourceNotFoundException``UnauthorizedException` 都继承自 `RuntimeException`,虽然能用,但错误信息的格式不够统一。如果重新做,我会设计一个通用的 `ApiException` 基类,包含错误码、错误信息和详细描述,这样前端解析错误会更方便。
**其次是 DTO 转换的方式**。目前我在 `PlaylistServiceImpl` 中用私有方法 `toDTO()` 进行转换,虽然能工作,但随着实体增多,这种方式会导致 Service 类越来越臃肿。更好的做法是使用 MapStruct 这样的映射框架,或者至少把转换逻辑抽取到独立的 Mapper 类中。
**第三是安全配置的细化**。目前的 `SecurityConfig` 把所有路径规则都写在一起,如果后续 API 增多,这个配置会变得很长且难以维护。我会考虑使用 `@PreAuthorize` 注解将权限控制下放到 Controller 方法级别,这样更直观,也更容易测试。
**最后是测试覆盖**。虽然公开测试都通过了,但我没有自己编写额外的单元测试来覆盖边界情况。如果时间充裕,我会为 Service 层编写更多测试用例,特别是针对权限检查和异常场景的测试。
---
## 3. AI 协同开发经验
这次开发中AI 在以下场景帮助很大:
**场景一JWT 实现**。我对 JWT 的 API 不太熟悉,于是问 AI"如何使用 jjwt 库生成和验证 JWT token"AI 给出了完整的代码示例,包括使用 `Jwts.builder()` 生成 token 和 `Jwts.parser()` 解析 token。这个回答直接帮我节省了大量查文档的时间。不过 AI 给的示例用的是旧版 API`setSubject()` 而非 `subject()`),我需要根据实际使用的 jjwt 0.12.x 版本进行调整。这让我学到:**AI 的知识可能有时效性,需要验证是否与当前使用的库版本匹配**。
**场景二Spring Security 配置**。我问 AI"如何配置 Spring Security 让某些路径公开访问,其他需要 JWT 认证?"AI 给出了 `SecurityFilterChain` 的配置方式,这个回答很有用。但 AI 最初建议我返回 403 而非 401我查阅 HTTP 规范后发现,未认证应该返回 401而无权限才是 403。这让我意识到**不能盲目接受 AI 的回答,特别是涉及规范和最佳实践的问题,需要自己判断**。
**总结**AI 是很好的"快速入门"工具,能帮我快速了解一个陌生技术的基本用法。但它的回答可能过时、可能有细节错误、可能不符合最佳实践。**正确的使用方式是把 AI 当作"高级搜索引擎",而非"权威答案"**。我需要理解 AI 给的每一行代码,而不是复制粘贴后祈祷它能工作。