跳到正文
JPA:白送的 CRUD,和它背后的理解缺口
JPA:白送的 CRUD,和它背后的理解缺口

JPA:白送的 CRUD,和它背后的理解缺口

接口有了,让数据落库。这篇用 Spring Data JPA 接 MySQL。不讲怎么配,讲「继承个接口就白送 CRUD」的爽和险——爽在省事,险在我可能根本不懂它在生成什么 SQL。

速读#

Spring Data JPA 的震撼在于继承接口就白送 CRUD,但「白送」也意味着 SQL 细节被框架藏起来。省事可以要,理解缺口不能放着不管;show-sql 是把抽象重新变得可见的第一步。

继承接口,CRUD 全白送#

public interface NoteRepository extends JpaRepository<Note, Long> {
List<Note> findByTitleContaining(String keyword);
}

savefindByIddeleteById 现成;连 findByTitleContaining 这种,JPA 也能按方法名生成 SQL——方法名被拆解成 findBy + Title + Containing,翻译成 where title like ?。第一次见挺震撼:我什么 SQL 都没写,活干了。

震撼之后:理解缺口#

「白送」意味着 SQL 是它生成的,不是我写的。不盯生成的 SQL,就不知道实际在干什么。任务完成了,理解留在框架那边。

这种状态我认识:Dockerfile 多阶段构建那次也「能跑不懂」,后来想加缓存优化才发现完全不理解 COPY --from=build 在干嘛。这次没有重蹈:

白送的第一时间就打开 show-sql: true,把生成的 SQL 打出来看。

spring:
jpa:
hibernate:
ddl-auto: update # 开发期自动建表,生产慎用
show-sql: true # 让生成的 SQL 可见

show-sql 是开发期的观察窗;生产上要看 SQL,走日志配置去看,别往标准输出裸打。)

盯着 SQL 看很快就见到了「省事的另一面」:查一批带关联的实体,控制台刷出一长串查询——先一条查询取回主表的 N 行,再为每一行各发一条查询去取关联数据。这就是常说的 N+1:写代码时只是一次 findAll(),跑起来是 1 + N 次查询。根子是两种模型的错配:我在代码里按对象导航,数据库擅长的是按集合一次算完,ORM 在中间默默用多次查询把前者翻译成后者。不开 show-sql,这种事静悄悄发生,数据量小的时候甚至察觉不到——等察觉时往往已经不在开发环境。复杂查询(关联、N+1)不能靠方法名猜,要靠看它生成了什么。

看见之后才有得选:改成一条 join 把关联一次取回,或者接受现状——数据量确实小,优化不划算。选哪个不重要,重要的是**「选」发生在我知情之后**,这就是可见性买回来的东西。

两个「能 ≠ 该」#

配置 / 做法方便在哪该不该
ddl-auto: update开发期自动建表生产让框架改表风险高,变更应受控
密码写进配置文件省事配置进 Git 后密钥收不回来;用 ${DB_PASSWORD}

ddl-auto 这一个键就值得停一下:update 只加不减,改错的列会一直留着;create 每次启动重建表,数据直接没了。开发期怎么方便怎么来,生产库的表结构变更必须是我审过的 SQL,不是框架启动时的副作用。

工具给的「方便」和工程上的「该不该」是两个问句,得分开答。

JPA vs MyBatis-Plus#

JPAMyBatis-Plus
强项简单 CRUD 极致省事复杂查询透明可控
弱项复杂查询仍要 JPQL,理解缺口大简单场景啰嗦一点

我的场景:简单 CRUD 多 + 偶尔复杂查询 → JPA 的省事值钱。复杂查询占大头时,我会更倾向条件构造器那一侧。

抽象不是越深越好#

这条线是从 SQLite 练手一路延续下来的:练手零运维 → 工程化换 MySQL → 再加 ORM。每加一层抽象,多一层理解缺口。

抽象是「省的事」和「藏的细节」之间的跷跷板。 show-sql: true 就是在这头加一个「细节可见」的对冲。

实体长这样时,骨架才算立住:

@Entity
@Table(name = "notes")
public class Note {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@Column(columnDefinition = "TEXT")
private String body;
}

带走两个判断:

  1. 白送的便利,要用「看得见它干了什么」对冲理解缺口
  2. 能自动 ≠ 该自动;生产配置受控
版权许可

CC BY-NC-SA 4.0 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

相关文章

s1oopX

登录 s1oopX