有时候一张表中会定义多个主键,即联合主键,Hibernate 对联合主键也提供了支持,由于 Annotation 现在用的比 XML 更加流行,则本文以 Annotation 讲解。
既然一张表中定义了联合主键,则在面向对象的思想中,他们都是主键,在 JAVA 中可以专门定义一个类来存放主键,Hibernate 文档说明此主键类必须实现 Serializable 接口,并且要重写 equals() 方法和 hashCode() 方法。定义如下主键类 ApplePk:
1: package cn.cdp.hibernate; 2: 3: import java.io.Serializable; 4: 5: import javax.persistence.Embeddable; 6: public class ApplePk implements Serializable { 7: private int id; 8: private int size; 9: 10: public ApplePk() { 11: } 12: 13: public ApplePk(int id, int size) { 14: this.id = id; 15: this.size = size; 16: } 17: 18: //Getters and setters omitted here... 19: 20: @Override 21: public boolean equals(Object obj) { 22: if (obj instanceof ApplePk) { 23: ApplePk ap = (ApplePk) obj; 24: if (ap.getId() == id && ap.getSize() == size) { 25: return true; 26: } 27: } 28: return false; 29: } 30: 31: @Override 32: public int hashCode() { 33: return new Integer(id).hashCode(); 34: } 35: 36: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }在 Annotation 中实现联合主键有多种方法:
方法一
在主键类头部加 @Embeddable:
1: @Embeddable 2: public class ApplePk implements Serializable { 3: //Code omitted here... 4: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }并且在需要持久化的对象中的主键对象上面加注解 @Id:
1: @Id 2: private ApplePk applePk; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }方法二
在需要持久化的对象中将主键对象加注解 @EmbeddedId 即可:
1: public class Apple { 2: @EmbeddedId 3: private ApplePk applePk; 4: //code omitted here... 5: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }方法三
创建如上 ApplePk 主键类,在持久化对象中声明同 ApplePk 类中相同的成员变量,并且都加上 @Id 注解,让后再在持久化对象头部加 @IdClass(ApplePk.class) 即可:
1: @Entity 2: @IdClass(ApplePk.class) 3: public class Apple { 4: @Id 5: private int id; 6: @Id 7: private int size; 8: //code omitted here... 9: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }