假設您設計了一個T_USER表格,當中有id、name、age與email四個欄位,而在Java程式的方面,您原先設計了一個User類別:
...
@Entity
@Table(name="T_USER")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age;
private String email;
........
}
@Entity
@Table(name="T_USER")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age;
private String email;
........
}
現在假設您基於商務上的設計需求,需要提高物件設計時的精細度,而將email資訊封裝至一個Email物件,讓它攜帶更多資訊或負有特定職責,而User類別變為如下設計:
- User.java
package onlyfun.caterpillar;
import java.io.Serializable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="T_USER")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Long age;
@Embedded
private Email Email;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public Email getEmail() {
return Email;
}
public void setEmail(Email Email) {
this.Email = Email;
}
}
其中Email封裝了郵件位址資訊,為另行設計的一個類別,您必須使用@Embedded標示,表示映射訊息是位於Email之中:
- Email.java
package onlyfun.caterpillar;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Embeddable;
@Embeddable
public class Email implements Serializable {
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void sendMail() {
System.out.println("Send mail to " + email);
}
}
Email類別上,則使用@Embeddable標示,注意在JPA的規格書中,目前不支援巢狀的嵌入類別,像Email這樣的物件稱之為值類型(value type)物件,它沒有自己的識別(identity),隸屬於某個實體物件,其生命週期跟隨著所隸屬的實體物件,值類型物件通常不會共用。
在儲存時,只要User設定好Email,儲存User物件時,會自動將Email中的屬性儲存至對應的欄位:
Email mailAddress = new Email();
mailAddress.setEmail("caterpillar.onlyfun@gmail.com");
User user = new User();
user.setName("caterpillar");
user.setAge(new Long(30));
user.setMailAddress(mailAddress);
EntityManager entityManager =
JPAUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction etx = entityManager.getTransaction();
etx.begin();
entityManager.persist(user);
etx.commit();
entityManager.close();
而載入User時,也會自動將欄位設定至Email中對應的屬性:
EntityManager entityManager =
JPAUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction etx = entityManager.getTransaction();
etx.begin();
User user = entityManager.find(User.class, id);
etx.commit();
entityManager.close();
user.getMailAddress().sendMail();
@Embedded可以搭配@AttributeOverride或@AttributeOverrides一同使用,以重新定義@Embeddable類別中的映射訊息,例如:
....
@Embedded
@AttributeOverride(name="email", column=@Column(name="CUST_STREET"))
private Email Email;
....