JPA 继承策略对比

相关概念:jpa

实体继承最值得关心的,不是注解怎么写,而是“最终会落成什么表结构,以及这会反过来怎样影响查询和维护”。

三种最常见策略

SINGLE_TABLE

所有父子实体共用一张表,通常靠一个类型字段区分。

它的直觉特征是:

  • 查询简单
  • 表会越来越宽
  • 子类特有字段在很多行上会是空值

适合层级不深、结构差异不大的场景。

JOINED

父类一张表,子类各自一张表,通过主键关联。

它的直觉特征是:

  • 结构更规整
  • 公共字段不会重复存储
  • 查询子类时通常要做 join

适合希望模型语义清晰、又不想把所有字段都压成一张大表的场景。

TABLE_PER_CLASS

每个实体类都有自己的完整表,父类字段会在子类表里重复出现。

它的直觉特征是:

  • 每张表都相对独立
  • 没有父子表 join 的负担
  • 公共字段会重复

适合子类之间差异较大、独立性很强的场景。

怎么选更稳

更稳的判断方式是先问三件事:

  • 子类之间的结构差异到底大不大
  • 未来更多是按父类统一查询,还是按子类独立查询
  • 更在意查询简单,还是更在意表结构规整

判断

如果暂时还没想清楚,默认用 SINGLE_TABLE 往往最省事;如果已经明显感觉“这一堆字段不该挤在一张表里”,就该认真看 JOINED;如果子类几乎已经是不同实体,只是概念上共享父类,再考虑 TABLE_PER_CLASS

额外提醒

很多框架都会在 JPA 语义上再包一层自己的行为,但底层取舍通常还是绕不开这三种思路。