JPA 中的组合ID Composite Primary Keys in JPA
1. 介绍
我在学习Spring Security的过程中,接触到了它的数据库结构,其中 authorities 表具有复合主键,那么在JPA中怎么定义复合主键呢?
2. 复合主键
所谓复合主键就是在一张表里面有两个或多个字段组成
In JPA, we have two options to define the composite keys: The @IdClass and @EmbeddedId annotations.
在 JPA 中我们有两个选项来定义复合主键喂,可能是新新景区吧,对呀,就是ID卡和嵌入ID的嗯注解,
为了定义复合组件,我们需要遵循以下的规则
- 复合组件类必须是public的
- 必须有一个没有参数的构造函数
- 必须定义equals和hashCode的方法
- 必须是可以系列化的
3. IdClass 注解
针对上面的Authority实体,我们先来定一个主键类,映射主键字段
class AuthorityPk(
var user: User? = null,
var authority:String? = null
) : Serializable
接下来我们把这个主键类和实体被关联起来,实现这个目的,我们使用IdClass注解,然后我们在实体类里面分别定义在主键类中定义过的ID字段,加上ID注解:
@Entity
@Table(name="authorities")
@IdClass(AuthorityPk::class)
data class Authority(
@Id
@ManyToOne
@JoinColumn(name="username")
@JsonBackReference
var user:User? = null,
@Id
var authority:String? = null
)
4. 使用 EmbeddedId 注解
@EmbeddedId 是替换 @IdClass 注解的另外一个复合主键方案.
同样上面的例子,先使用 @Embeddable 注解一个主键类:
@Embeddable
class AuthorityPk(
@ManyToOne
@JoinColumn(name="username")
@JsonBackReference
var user: User? = null,
var authority:String? = null
) : Serializable
然后把这个注解类整个作为主键,通过 @EmbeddedId 注解:
@Entity
@Table(name="authorities")
data class Authority(@EmbeddedId
var id:AuthorityPk)
5. @IdClass 和 @EmbeddedId 区别
通过例子我们很明白的看到 @IdClass 在实体类中需要重新定义主键字段,而通过 @EmbeddedId 我们只需要在实体类中使用一个主键类对象。
具体的在应用中可以通过 JPQL 的查询来体会其中的区别:
如果你使用 @IdClass , 查询是这样的:
SELECT authority.user FROM Authority authority
而使用 @EmbeddedId, 我们将会这样查询:
SELECT authority.id.user FROM Authority authority
两种方式都有其应用场景,具体