天天看點

eclipse + JBoss 5 + EJB3開發指南(7):實作Entity Bean的一對一(on

本文為原創,如需轉載,請注明作者和出處,謝謝!

    一對一映射是很常用的。在一般情況下,一個主表通過外鍵和從表形成一對一的關系。在EJB3中使用@OneToOne注釋來映射。一對一關系除了使用外鍵進行關聯外,也可以采用共享主鍵的方式連接配接兩個表。先看看如下兩個表的結構:

eclipse + JBoss 5 + EJB3開發指南(7):實作Entity Bean的一對一(on

圖1  t_customers

eclipse + JBoss 5 + EJB3開發指南(7):實作Entity Bean的一對一(on

圖2  t_referees

    t_customers和t_referees表形成了一對一的關系。t_customers表通過referee_id與t_referees表相連。與t_customers表對應的實體Bean的代碼如下:

Code:

package entity;  

import java.util.Collection;  

import javax.persistence.Entity;  

import javax.persistence.FetchType;  

import javax.persistence.GeneratedValue;  

import javax.persistence.GenerationType;  

import javax.persistence.Id;  

import javax.persistence.JoinColumn;  

import javax.persistence.OneToOne;  

import javax.persistence.Table;  

@Entity  

@Table(name = "t_customers")  

public class Customer  

{  

    private int id;  

    private String name;  

    private Referee referee;  

    @Id  

    @GeneratedValue(strategy = GenerationType.IDENTITY)  

    public int getId()  

    {  

        return id;  

    }  

    public void setId(int id)  

        this.id = id;  

    public String getName()  

        return name;  

    public void setName(String name)  

        this.name = name;  

    @OneToOne  

    public Referee getReferee()  

        return referee;  

    public void setReferee(Referee referee)  

        this.referee = referee;  

    從上面的代碼可以看出,getReferee方法使用了@OneToOne進行設定。在裝載Customer對象的同時,Referee對象會被同時裝 載,而預設的外鍵字段就是Customer類中的referee屬性名 + "_" + id,也就是referee_id。下面看一下與t_referees表對應的實體Bean代碼:

@Table(name="t_referees")  

public class Referee  

    private Customer customer;  

    @OneToOne(mappedBy="referee")  

    public Customer getCustomer()  

        return customer;  

    public void setCustomer(Customer customer)  

        this.customer = customer;  

    Referee類使用了customer屬性映射了Customer對象,實際上,這是一個雙向的one-to-one映射。這時,在Referee類的 customer屬性的getter方法的@OneToOne注釋中,需要使用mappedBy屬性來指定主表(Customer)中的映射從表的屬性名 (referee)。

    我們可以使用下面的代碼進行測試:

System.out.println(em.find(Referee.class, 1).getCustomer().getName());  

Customer customer = new Customer();  

customer.setName("微軟");  

Referee referee = new Referee();  

referee.setName("趙軍");  

em.persist(referee);          

customer.setReferee(referee);  

em.persist(customer); 

    如果要覆寫預設的名鍵名,例如,外鍵名為referee1_id,可以兩種方法使EJB3容器使用新的外鍵:

    1.  修改Customer類中的referee屬性的getter和setter方法為getReferee1和setReferee1,并将Referee類中mappedBy屬性的值修改成referee1。

    2.  使用@JoinColumn注釋設定新的外鍵名,這種方法隻需要修改Customer類的getReferee方法上面注釋即可,代碼如下:

@OneToOne  

@JoinColumn(name="referee1_id")  

public Referee getReferee()  

    return referee;  

    one-to-one關系還可以共享主鍵,也就是一個表的主鍵的值依賴于另一個表的主鍵的值。是以,在這種情況下,就不再需要t_customers表中 的referee_id字段了。由于t_referees表的id字段值依賴于t_customers表的id字段值,是以,需要将t_referees 表中的id字段值的自增類型去掉。

    在EJB3中使用@PrimaryKeyJoinColumn注釋來實作主鍵的共享。首先需要修改Customer類的getReferee方法上方的注釋,修改後的代碼如下:

@OneToOne(cascade=CascadeType.ALL)  

@PrimaryKeyJoinColumn  

}  

    然後要修改Referee類中的getCustomer和getId方法上方的注釋,修改後的代碼如下:

public Customer getCustomer()  

    return customer;  

@Id  

@GeneratedValue(generator = "pkGenerator")  

@GenericGenerator(name = "pkGenerator", strategy = "foreign",  

   parameters = @Parameter(name = "property", value = "customer"))  

public int getId()  

    return id;  

    其中@GenericGenerator注釋表示這個id屬性是外鍵,并且依賴于customer屬性對應的實體Bean的id屬性值(主鍵值)。

    另外還要注意一點,由于t_referees表的id的自增類型已經去掉,而且該值依賴于t_customers表的id字段值,是以,就不能直接持久化Referee對象了,而在持久化Customer對象的同時,EJB3容器會自動将Referee持久化的。

繼續閱讀