[置頂] 持久化API(JPA)系列(七)實體關系映射(ORM)之單表映射@IdClass
來源:程序員人生 發布時間:2015-05-11 09:28:17 閱讀次數:2527次
通過之前的文章,我們了解到@Table、@Column、@Id實現了單表的映照,并且書劍有1個@Id指定的唯1字段。有時我們的數據表或許是有多個主鍵聯合組成的,因此對單表映照的主鍵,還可以進行以下兩種聯合主鍵映照。
聯合主鍵:使用@IdClass指定外部主鍵
聯合主鍵:使用@EmbeddedId嵌入外部主鍵
下面通過實例來看這兩種主鍵的開發方法。
Demo:設計1個家庭表Family的數據結構

======================================================================
(1)聯合主鍵:使用@IdClass指定外部主鍵
步驟:
1、建立1個主鍵類:類中對應了主鍵字段
2、在實體Bean中通過@IdClass注釋符援用該類
以實現外部主鍵的援用。
1)新建外部主鍵類FamilyPK.java
由于Family中設置聯合主鍵man和woman,因另外部主鍵類FamilyPK也需要定義兩個一樣的變量,并添加1個以這兩個變量為輸入的構造函數,同時添加getter/setter函數。
作為外部主鍵需滿足:
1.必須實現Serializable接口
2.必須有默許的public無參數的構造方法
3.必須覆蓋equals()和hashCode()方法。
equals()方法用于判斷兩個對象是不是相同,EntityManager通過find()方法來查找實體,是根據equals()的返回值來判斷的。本例中,只有對象的man和woman值完全相同或屬于同1個對象時才返回true,否則返回false。
hashCode()方法返回當前對象的哈希碼。生成的hashCode()相同的幾率越小越好,算法可以進行優化。
package com.tgb.itoo.exam.entity;
import java.io.Serializable;
@SuppressWarnings("serial")
public class FamilyPK implements Serializable {
private String man;//丈夫
private String woman;//妻子
public String getMan() {
return man;
}
public void setMan(String man) {
this.man = man;
}
public String getWoman() {
return woman;
}
public void setWoman(String woman) {
this.woman = woman;
}
public FamilyPK() {
}
public FamilyPK(String man, String woman) {
this.man = man;
this.woman = woman;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((man == null) ? 0 : man.hashCode());
result = prime * result + ((woman == null) ? 0 : woman.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FamilyPK other = (FamilyPK) obj;
if (man == null) {
if (other.man != null)
return false;
} else if (!man.equals(other.man))
return false;
if (woman == null) {
if (other.woman != null)
return false;
} else if (!woman.equals(other.woman))
return false;
return true;
}
}
2)使用@IdClass在實體Bean類Family.java中指定外部主鍵。
通過注釋符來設置與表、字段的映照關系。
注意,該實體中需要標注聯合主鍵:
1、在man和woman的getter函數前都添加@Id注釋符,表示都是主鍵
2、在類名錢使用@IdClass援用外部主鍵類
package com.tgb.itoo.exam.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
@SuppressWarnings("serial")
@Entity
@Table(name="family")
@IdClass(FamilyPK.class)
public class Family implements Serializable {
private String man;// 丈夫
private String woman;// 棋子
private String address;// 地址
@Id
public String getMan() {
return man;
}
public void setMan(String man) {
this.man = man;
}
@Id
public String getWoman() {
return woman;
}
public void setWoman(String woman) {
this.woman = woman;
}
@Column(name="address" ,length=100)
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
3)新建遠程接口類FamilyDAORemote.java
定義兩個接口:新增、根據主鍵查詢
package com.tgb.itoo.exam.service;
import javax.ejb.Remote;
import com.tgb.itoo.exam.entity.Family;
@Remote
public interface FamilyDAORemote {
// 新增
public boolean insert(Family family);
// 插入
public Family selectByPK(String man, String woman);
}
4)開發實現類FamilyDAO.java
1.首先構造1個主鍵對象FamilyPK
2.后調用find()方法根據該主鍵對象進行查詢
package com.tgb.itoo.exam.papermanage.serviceimpl;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import com.tgb.itoo.exam.entity.Family;
import com.tgb.itoo.exam.entity.FamilyPK;
import com.tgb.itoo.exam.service.FamilyDAORemote;
@Stateless
public class FamilyDAO implements FamilyDAORemote {
protected EntityManager em;
@Override
public boolean insert(Family family) {
try {
em.persist(family);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public Family selectByPK(String man, String woman) {
FamilyPK epk = new FamilyPK(man, woman);
return em.find(Family.class, epk);
}
}
5)測試:客戶端調用
package com.tgb.itoo.exam.papermanage.serviceimpl;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.tgb.itoo.exam.entity.Family;
import com.tgb.itoo.exam.service.FamilyDAORemote;
public class FamilyDAOClient {
public static void main(String[] args) throws NamingException {
//........
InitialContext ctx=new InitialContext();
FamilyDAORemote familyDAO=(FamilyDAORemote) ctx.lookup("FamilyDAO/remote");
//新增
Family family=new Family();
family.setMan("丈夫");
family.setWoman("妻子");
family.setAddress("地址");
familyDAO.insert(family);
//查詢
Family family2=familyDAO.selectByPK("丈夫的名稱", "妻子的名稱");
System.out.println(family2.getAddress());
}
}
下文中將通過Demo演示《聯合主鍵:使用@EmbeddedId嵌入外部主鍵》
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈