在Java中,如果需要设置联合主键(由多个属性列组成)对应数据库表的主键,可以使用 @IdClass
或者 @Embedded
1. 使用 @IdClass
这种方式需要创建一个单独的类来表示联合主键,并实现 Serializable
接口。
Id
注解。这两种方式都可以实现联合主键的映射,但略有不同。
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
// 联合主键类
class UserId implements Serializable {
private Long id;
private String username;
// 默认构造函数
public UserId() {}
public UserId(Long id, String username) {
this.id = id;
this.username = username;
}
// hashCode 和 equals 方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof UserId)) return false;
UserId userId = (UserId) o;
return Objects.equals(id, userId.id) && Objects.equals(username, userId.username);
}
@Override
public int hashCode() {
return Objects.hash(id, username);
}
}
// 实体类
@Entity
@Table(name = "users")
@IdClass(UserId.class) // 指定联合主键类
public class User {
@Id
private Long id;
@Id
private String username;
private String email;
// 默认构造函数
public User() {}
// 其他构造函数、getter 和 setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2. 使用 @EmbeddedId
这种方式使用一个嵌入式的类来表示联合主键。与 @IdClass
方法不同,它通常是通过一个 @Embeddable
注解的类来实现。
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
// 嵌入式ID类
@Embeddable
class UserId implements Serializable {
private Long id;
private String username;
// 默认构造函数
public UserId() {}
public UserId(Long id, String username) {
this.id = id;
this.username = username;
}
// hashCode 和 equals 方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof UserId)) return false;
UserId userId = (UserId) o;
return Objects.equals(id, userId.id) && Objects.equals(username, userId.username);
}
@Override
public int hashCode() {
return Objects.hash(id, username);
}
}
// 实体类
@Entity
@Table(name = "users")
public class User {
@EmbeddedId // 指定使用嵌入式主键
private UserId userId;
private String email;
// 默认构造函数
public User() {}
// 其他构造函数、getter 和 setter
public UserId getUserId() {
return userId;
}
public void setUserId(UserId userId) {
this.userId = userId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
总结
- @IdClass:适合简单的联合主键,不需要独立的对象来表示。
- @EmbeddedId:使用嵌入式ID类,有助于更好地封装和管理主键逻辑,通常推荐这种方式。
根据具体的需求和应用场景,选择合适的方式来实现联合主键。