JPA的Embeddable Objects
[ 2006-11-14 18:27:56 | 作者:
LALFASHI ]
在hibernate中實(shí)現(xiàn)自定義類型,只要實(shí)現(xiàn)UserType接口即可或者以Compnent的形式提供.JPA的@Embedded有點(diǎn)類似,通過此注釋可以在你的Entity中使用一般的java對(duì)象,此對(duì)象需要用@Embeddable標(biāo)注
舉個(gè)簡單例子:Person類有一個(gè)name屬性,name應(yīng)該有firstName,lastName兩個(gè)屬性,一般的寫法直接在entity中寫兩個(gè)屬性:
private String firstName;
private String lastName;
我們可以用一個(gè)Name類來代替這樣的寫法,此類包含了firstName和lastName,如此一來,我們?cè)趀ntity只要這樣寫:
private Name name;
就可以了.那么Name類大概是什么樣呢?如下:
package com.denny_blue.ejb3.entity;
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class Name implements Serializable {
private String firstName;
private String lastName;
public Name() {
}
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return firstName+ +lastName;
}
}
值的注意的是:
1.必須要實(shí)現(xiàn)serializable接口
2.需要有無參的構(gòu)造函數(shù)
3.@Embeddable注釋,表示此類可以被插入某個(gè)entity中
還沒完!Person類中的name屬性需要與數(shù)據(jù)庫表中的first,last兩個(gè)字段進(jìn)行映射,如下:
@Embedded
@AttributeOverrides( {
@AttributeOverride(name = firstName, column = @Column(name = first_name)),
@AttributeOverride(name = lastName, column = @Column(name = last_name)) })
public Name getName() {
return name;
}
通過@AttributeOverride注釋來指定Name類的firstName,lastName與數(shù)據(jù)庫中表的first_name,last_name進(jìn)行映射.
很簡單吧,看起來蠻爽的.可發(fā)現(xiàn)一個(gè)不大不小的缺點(diǎn),比如,我要查詢一個(gè)姓名dennis zane的人,如果是hibernate,我也許這樣做:
session.createQuery(from Person p where p.name=?).setParameter(0,name).list();
Hibernate將自動(dòng)將你的自定義類型進(jìn)行匹配,可如果我在JPA中這樣寫:
em.createQuery(select p from Person p where p.name=:name).setParameter(name,name);
查詢出錯(cuò)...郁悶,把整個(gè)name對(duì)象作為查詢參數(shù)傳進(jìn)去就出錯(cuò),我非要這樣寫:
em.createQuery(select p from Person p where p.name.firstName=:name1 and p.name.lastName=:name2).setParameter(name1,name.getFirstName()).setParameter(name2,name.getLastName);
也就是需要你自己去映射Name的每一個(gè)屬性.