SpringData JPA复合主键 的使用
程序员文章站
2022-04-24 22:40:48
...
复合主键 和 联合主键的区别
复合主键 : 一张表中 , 两个字段 确定一条唯一数据 ;
联合主键 : 表A , 表 B 两张表 , 通过中间表 , 确定两张表的对应关系 ;
(中间表三个字段 : id , 表A_id, 表B_id) ; 此时中间表的id 称为 联合主键 ;
spring jpa 复合主键 的使用
使用场景 : 订单类的 , 订单编号 ORDER_NUM + 订单子项目 INNER_NUM , 两个字段 组成 复合主键 , 确定唯一数据 ;
- 方式一 : 使用 @Embeddable 注解主键类 ; 然后 实体类 继承自主键类 ; (该方式书写简洁, 但是不易懂)
1 . 编写一个复合主键类 ; 命名可以在 实体类名后 + PK 用于 区分 主键类 ;
@Embeddable // 1. 在复合主键的类上,使用注解@Embeddable
public class OrderPK implements Serializable { // 2. 实现Serializable接口(否则会报错);
@Column(name = "ORDER_NUM")
private String orderNum; // 主单号
@Column(name = "INNER_NUM")
private String innerNum; // 子项目
// 3. 无参构造
// 有默认的public无参数的构造方法(在我这个实例中,我没有添加有参构造方法,所以采用默认的构造方法)
// 如果你在实体类里有有参构造方法,那么一定要有一个无参构造方法,否则运行的时候会报错
// 4. 重写equals和hashCode方法。
// equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,
// 是根据equals的返回值来判断的。
// hashCode方法返回当前对象的哈希码
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OrderPK)) return false;
OrderPK orderPK = (OrderPK) o;
if (orderNum != null ? !orderNum.equals(orderPK.orderNum) : orderPK.orderNum != null) return false;
return innerNum != null ? innerNum.equals(orderPK.innerNum) : orderPK.innerNum == null;
}
@Override
public int hashCode() {
int result = orderNum != null ? orderNum.hashCode() : 0;
result = 31 * result + (innerNum != null ? innerNum.hashCode() : 0);
return result;
}
// 生成 get set toString 此处省略
}
2 . 编写实体类 , 继承 主键类;
@Entity
@Table(name = "ORDER")
public class Order extends OrderPK {
// 复合主键要用这个注解
@EmbeddedId
private OrderPK id;
// 复合主键的两个字段, 在实体类中,就不用写了
@Column(name = "OTHER_FIELD")
private String otherField; // 其他字段
// 生成 get set toString 此处省略
}
-
方式二 : 采用 @IdClass 来注解复合主键; ( 推荐 , 复合主键字段, 在实体类中, 直接有体现 , 看起来简单明了)
1 . 编写一个复合主键类;
// @Embeddable
public class OrderPK implements Serializable {
// @Column(name = "ORDER_NUM")
private String orderNum; // 主单号
// @Column(name = "INNER_NUM")
private String innerNum; // 子项目
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OrderPK)) return false;
OrderPK orderPK = (OrderPK) o;
if (orderNum != null ? !orderNum.equals(orderPK.orderNum) : orderPK.orderNum != null) return false;
return innerNum != null ? innerNum.equals(orderPK.innerNum) : orderPK.innerNum == null;
}
@Override
public int hashCode() {
int result = orderNum != null ? orderNum.hashCode() : 0;
result = 31 * result + (innerNum != null ? innerNum.hashCode() : 0);
return result;
}
// 生成 get set toString 此处省略
}
2 . 编写实体类
@Entity
@Table(name = "ORDER")
@IdClass(OrderPK.class) // 添加 @IdClass 注解 , 指定 复合主键类
public class Order implements Serializable { // 不用再继承 复合主键类
// @EmbeddedId
// private OrderPK id;
@Id // 添加复合主键标识
@Column(name = "ORDER_NUM")
private String orderNum; // 主单号
@Id // 添加复合主键标识
@Column(name = "INNER_NUM")
private String innerNum; // 子项目
@Column(name = "OTHER_FIELD")
private String otherField; // 其他字段
// 生成 get set toString 此处省略
}
下一篇: Html中图片和div居中