有时一个实体的主键可能同时为多个例如同样是之前使用的CustomerEO实体需要通过name和email来查找指定实体当且仅当name和email的值完全相同时才认为是相同的实体对象要配置这样的复合主键步骤如以下所示
()编写一个复合主键的类CustomerPK代码如下
CustomerPKjava
importjavaioSerializable;
publicclassCustomerPKimplementsSerializable{
publicCustomerPK(){
}
publicCustomerPK(StringnameStringemail){
thisname=name;
thisemail=email;
}
privateStringemail;
publicStringgetEmail(){
returnemail;
}
publicvoidsetEmail(Stringemail){
thisemail=email;
}
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
thisname=name;
}
@Override
publicinthashCode(){
finalintPRIME=;
intresult=;
result=PRIME*result+((email==null)?:emailhashCode());
result=PRIME*result+((name==null)?:namehashCode());
returnresult;
}
@Override
publicbooleanequals(Objectobj){
if(this==obj)
returntrue;
if(obj==null)
returnfalse;
if(getClass()!=objgetClass())
returnfalse;
finalCustomerPKother=(CustomerPK)obj;
if(email==null){
if(otheremail!=null)
returnfalse;
}elseif(!emailequals(otheremail))
returnfalse;
if(name==null){
if(othername!=null)
returnfalse;
}elseif(!nameequals(othername))
returnfalse;
returntrue;
}
}
作为符合主键类要满足以下几点要求
l必须实现Serializable接口
l必须有默认的public无参数的构造方法
l必须覆盖equals和hashCode方法equals方法用于判断两个对象是否相同EntityManger通过find方法来查找Entity 时是根据equals的返回值来判断的本例中只有对象的name和email值完全相同时或同一个对象时则返回true否则返回false hashCode方法返回当前对象的哈希码生成的hashCode相同的概率越小越好算法可以进行优化
()通过@IdClass注释在实体中标注复合主键实体代码如下
@Entity
@Table(name=customer)
@IdClass(CustomerPKclass)
publicclassCustomerEOimplementsjavaioSerializable{
privateIntegerid;
publicIntegergetId(){
returnthisid;
}
publicvoidsetId(Integerid){
thisid=id;
}
privateStringname;
@Id
publicStringgetName(){
returnthisname;
}
publicvoidsetName(Stringname){
thisname=name;
}
privateStringemail;
@Id
publicStringgetEmail(){
returnemail;
}
publicvoidsetEmail(Stringemail){
thisemail=email;
}
}
标注复合主键时需要注意以下几个问题
l@IdClass标注用于标注实体所使用主键规则的类它的定义如下所示
@Target({TYPE})@Retention(RUNTIME)
public@interfaceIdClass{
Classvalue();
}
属性Class表示符合主键所使用的类本例中使用CustomerPK这个复合主键类
l在实体中同时标注主键的属性本例中在email和name的getter方法前标注@Id表示符合主键使用这两个属性
()这样定义实体的复合主键后通过以下代码便可以获得指定的实体对象
CustomerPKcpk=newCustomerPK(Janetcn);
CustomerEOinstance=entityManagerfind(CustomerEOclasscpk);