在 JPA 中,有几种方法可以创建复合键字段。让我们看看使用@Embeddable annotation
.
让我们从 Entity 类开始。
@Entity
@Table
public class TraceRecord {
@Id
private TraceRecordPk id;
@Version
@Transient
private int version;
@Column(columnDefinition = "char")
private String durationOfCall;
@Column(columnDefinition = "char")
private String digitsDialed;
@Column(columnDefinition = "char")
private String prefixCalled;
@Column(columnDefinition = "char")
private String areaCodeCalled;
@Column(columnDefinition = "char")
private String numberCalled;
}
这是一个非常简单的 Entity 类,带有一个 @Id 和 @Version 字段以及一些 @Column 定义。无需过多介绍,您将看到@Version 字段也被注释为@Transient。我这样做只是因为我的表也没有用于跟踪版本的列,但是我的数据库是日志记录的,所以我不太关心版本控制。您还会注意到@Column 字段在 columnDefinition 属性上设置了“char”值。这是因为我的表中的字段被定义为 char 而不是 varchar。如果它们是 varchar,我不需要这样做,因为默认情况下 String 映射到 varchar 字段。
这个@Id
领域是我现在感兴趣的。它不是标准的 Java 类型,而是我自己定义的类。这是那堂课。
@Embeddable
public class TraceRecordPk implements Serializable {
private static final long serialVersionUID = 1L;
@Temporal(TemporalType.DATE)
@Column
private Date dateOfCall;
@Column(columnDefinition="char")
private String timeOfCall;
@Column(columnDefinition="char")
private String callingParty;
/**
* Constructor that takes values for all 3 members.
*
* @param dateOfCall Date the call was made
* @param timeOfCall Time the call was made
* @param callingParty Extension from which the call originated
*/
public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) {
this.dateOfCall = dateOfCall;
this.timeOfCall = timeOfCall;
this.callingParty = callingParty;
}
}
为了使这个类能够成为实体类上的@Id 字段,它需要像我之前提到的那样使用@Embeddable 进行注释。我为复合键选择的 3 个字段只是普通的 @Column 定义。我没有为每个字段创建 getter/setter,而是简单地实现了一个构造函数,它为所有 3 个字段获取值,使任何实例都不可变。当使用 @Embeddable 注释一个类时,该类将需要实现 Serializable。所以我添加了一个默认的serialVersionUID 来适应。
现在您已经创建了一个用 注释的类@Embeddable
,您现在可以将它用作 Entity 类中 @Id 字段的类型。简单的东西嗯。