前文介绍了 使用Spring Data JPA 实现数据读取,工作中有时会碰到联合主键的情况,本文来看看如何配置拥有联合主键的实体类
仍以前文中的 CATEGORY
表为例,可以看到这里设置了 CATEGORY_ID
和 CATEGORY_NM
的联合主键。
定义联合主键需要遵守一些规则(具体可参考 JPA规范 - Primary Keys and Entity Identity):
- 主键类必须是
public
且有public
修饰的无参构造器 - 主键类必须序列化
- 主键类必须定义
equals
和hashCode
方法
此外,我们有两种方式可以配置联合主键:
- @IdClass
- @EmbeddedId
@IdClass 配合 @Id
创建一个用于存储主键字段的class
public class CategoryId implements Serializable {
private static final long serialVersionUID = 1017853314829862199L;
private Integer categoryId;
private String categoryNm;
// No-Arg Constructor
// Getter and Setter
}
然后在 Category
类中使用 @IdClass
和 @Id
来分别标记类和字段:
@Entity
@Table(name = "CATEGORY")
@IdClass(CategoryId.class) // 标记联合主键类
public class Category {
private static final long serialVersionUID = 1017853314829862199L;
@Id // 标记主键对应的字段
@Column(name = "CATEGORY_ID")
private Integer categoryId;
@Id // 标记主键对应的字段
@Column(name = "CATEGORY_NM")
private String categoryNm;
@Column(name = "CREATE_ID")
private String createId;
// other fields, getters and setters
}
@EmbeddedId 配合 @Embeddable
我们配置一个 CategoryId
类,并使用 @Embeddable
标记这个类
@Embeddable
public class CategoryId implements Serializable {
private static final long serialVersionUID = 1017853314829862199L;
private Integer categoryId;
private String categoryNm;
// No-Arg Constructor
// Getter and Setter
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CategoryId entity = (CategoryId) o;
return Objects.equals(this.categoryNm, entity.categoryNm) &&
Objects.equals(this.categoryId, entity.categoryId);
}
@Override
public int hashCode() {
return Objects.hash(categoryNm, categoryId);
}
}
然后我们需要在 Category
类中的对应字段上标记 @EmbeddedId
来嵌入这个id class
@Entity
@Table(name = "CATEGORY")
public class Category {
@EmbeddedId
private CategoryId id;
@Column(name = "CREATE_ID")
private String createId;
// other fields, getters and setters
}
这样我们就完成了entity以及其联合主键的配置,但在获取结果集的使用上这两种类型的配置会有一些区别。
比如在使用 @IdClass, @Id
的配置中,可以直接使用 category.getCreateId()
。而使用了 @EmbeddedId, @Embeddable
的配置中,需要category.getCategoryId().getCategoryNm()
才能得到结果。
以上就是最简单的关于联合主键的配置和用法。