@MappedSuperclass
基於程式碼複用和模型分離的思想,在專案開發中使用JPA的@MappedSuperclass註解將實體類的多個屬性分別封裝到不同的非實體類中。
1.@MappedSuperclass註解只能標準在類上:@Target({java.lang.annotation.ElementType.TYPE})
2.標註為@MappedSuperclass的類將不是一個完整的實體類,他將不會對映到資料庫表,但是他的屬性都將對映到其子類的資料庫欄位中。
3.標註為@MappedSuperclass的類不能再標註@Entity或@Table註解,也無需實現序列化介面。
但是如果一個標註為@MappedSuperclass的類繼承了另外一個實體類或者另外一個同樣標註了@MappedSuperclass的類的話,他將可以使用@AttributeOverride或@AttributeOverrides註解重定義其父類(無論是否是實體類)的屬性對映到資料庫表中的欄位。
比如可以重定義欄位名或長度等屬性,使用@AttributeOverride中的子屬性@Column進行具體的定義。
注意:對於其父類中標註@Lob註解的屬性將不能過載,並且@AttributeOverride裡的@Column設定都將不起作用。
JPA規範中對@Lob註解並沒有說明不能同時標註@Column註解,但是在實際使用中Hibernate JPA不支援這中標註方式。
4.此外,這樣的類還可以直接標註@EntityListeners實體監聽器,他的作用範圍僅在其所有繼承類中,並且實體監聽器同樣可以保被其子類繼承或過載。
5.標註為@MappedSuperclass的類其屬性最好設定為protected或default型別的,以保證其同一個包下的子類可以直接呼叫它的屬性。便於實體監聽器或帶引數建構函式的操作。
6.由於標註為@MappedSuperclass的類將不是一個完整的實體類,因此其不能標註@Table,並且無法使用@UniqueConstraint設定欄位的Unique屬性,這一點以及對屬性型別過載(如過載標註為@Lob的屬性)的支援JPA規範還有待改進。
7.可以同時標註@DiscriminatorValue註解,以設定實體子類的實體標識欄位的值。該屬性一般是在實體繼承的時候使用的較多,但是在實體對映的時候可以不用設定。
8.比較實體繼承與實體對映的區別:
實體繼承的三種策略分別是:SINGLE_TABLE(所有繼承的實體都儲存在同一張資料庫表中),JOINED(每個實體子類都將儲存在一個單獨的表中),TABLE_PER_CLASS(有繼承關係的所有實體類都將儲存在單獨的表中)。
實體對映最類似於JOINED實體繼承方式,他也是將實體子類單獨儲存為一張表,但是兩者最大的區別就在於:查詢的時候JOINED使用的是多型查詢,在查詢父類時其所有實體子類的資料也將同時被查詢出,因此查詢時間和效能都將有影響。但是實體對映方式的資料庫查詢等同於沒有實體繼承關係的查詢,也就是說,他僅在實體層體現出一種繼承的關係卻並沒有在資料庫中體現這樣一種關係,他的操作都是獨立的並且將不會影響到實體子類。
P.S.文中部分語義不清或描述含糊甚至定義錯誤的,請指正,期待共同進步!