1. 程式人生 > >持久化API(JPA)系列(七)實體關係對映(ORM)之單表對映@IdClass

持久化API(JPA)系列(七)實體關係對映(ORM)之單表對映@IdClass

通過以前的文章,我們瞭解到@Table、@Column、@Id實現了單表的對映,並且書劍有一個@Id指定的唯一欄位。有時我們的資料表也許是有多個主鍵聯合組成的,因此對於單表對映的主鍵,還可以進行如下兩種聯合主鍵對映。
        聯合主鍵:使用@IdClass指定外部主鍵
        聯合主鍵:使用@EmbeddedId嵌入外部主鍵

下面通過例項來看這兩種主鍵的開發方法。
Demo:設計一個家庭表Family的資料結構
 

======================================================================

(一)聯合主鍵:使用@IdClass指定外部主鍵

步驟:
    1、建立一個主鍵類:類中對應了主鍵欄位
    2、在實體Bean中通過@IdClass註釋符引用該類
以實現外部主鍵的引用。

1)新建外部主鍵類FamilyPK.java
由於Family中設定聯合主鍵man和woman,因此外部主鍵類FamilyPK也需要定義兩個同樣的變數,並新增一個以這兩個變數為輸入的建構函式,同時新增getter/setter函式。
作為外部主鍵需滿足:
1.必須實現Serializable介面
2.必須有預設的public無引數的構造方法
3.必須覆蓋equals()和hashCode()方法。
equals()方法用於判斷兩個物件是否相同,EntityManager通過find()方法來查詢實體,是根據equals()的返回值來判斷的。本例中,只有物件的man和woman值完全相同或屬於同一個物件時才返回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.首先構造一個主鍵物件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());
    }
 
}

--------------------- 
作者:chestnut_lan 
來源:CSDN 
原文:https://blog.csdn.net/zhaolijing2012/article/details/45396151 
版權宣告:本文為博主原創文章,轉載請附上博文連結!