延遲加載與即時加載
例如Person類和Email類是1對多關系,如果設為即時加載,當加載Person時,會自動加載Email,如果設置為延遲加載,當第1次調用person.getEmails()時才會履行SQL語句加載Email注解配置時,@OnetToMany(Fetch = FetchType.EAGER)為即時加載,Fetch = FetchType.LAZY為延遲加載延遲加載和即時加載的策略適用于所有1對多、多對1、多對多等所有的實體關系1般來講,延遲加載要比即時加載節省資源,但是如果處理不當,延遲加載容易拋出LazyInitializationException異常,解決當方法有兩種,1種是在Session關閉之前調用1下,person.getEmails()方法,逼迫Hibernate加載數據,這是最經常使用的方式,還有1種是延遲Session的范圍,使Session關閉前完成所有的業務邏輯,在web程序中有些工具也能延長Session的范圍,例如Spring的OpenSessionInViewFilter,能把Session擴大到所有的web資源,包括Servlet層、JSP層、DAO層、Service層
單邊1對多
1方有集合屬性,包括多個多方,而多方沒有1方的援用import javax.persistence.*; //“1"方 @Entity @Table(name="tb_person") public class Person{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; @OneToMany(fetch = FetchType.EAGER,targetEntity = Email.class,cascade={ CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE, CascadeType.REFRESH }) @JoinColumns(value= {@JoinColumn(name="person_id",referencedColumnName="id")}) @OrderBy(value = “email desc") private List<Email> emails = new ArrayList<Email>(); //在email對應的表中產生1個person_id字段,援用person標的id // referencedColumnName指的是實體類的關聯列,默許為主鍵,可省略 //setter、getter略 } //“多"方 @Entity @Table(name="tb_email") public class Email{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String email; //setter、getter略 }
<hibernate-mapping package="com.clf.hibernate.bean"> <class name="Person" table="tb_person"> <id name="id" column="id"> <generator class="native"> </id> <property name="name"/> <bag name="emails" cascade="all" lazy="false" where="email like %@%" order-by="email"> <key column="email_id"></key> <one-to-many class="com.clf.hibernate.bean.Email" /> </bag> </class> </ hibernate-mapping > <hibernate-mapping package="com.clf.hibernate.bean"> <class name="Email" table="tb_eamil"> <id name="id" column="id"> <generator class="native"> </id> <property name="email"/> </class> </ hibernate-mapping >
如果集合屬性使用的是Set而非List,則XML配置時需要使用<set>標簽而不是<bag>標簽,而且不能使用order-by屬性JPA(Java Persistence API)要求實體類必須為POJO,而不能為String等基本類型,換句話說,電子郵件必須封裝為Email對象,即便它只有1個String屬性而XML配置允許直接使用String作為實體類,而不需要封裝成1個Email對象配置改動以下<bag name="emails" cascade="all" lazy="false" where="email like %@%" order-by="email"> <key column="email_id"></key> <element type="String" column="email" /> </bag>
單邊多對1
//“1"方 @Entity @Table(name = "tb_table") public class Type{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(unique = true) private String name; //setter、getter方法略 } //“多"方 @Entity @Table(name = <span style="font-family: Arial, Helvetica, sans-serif;">"</span><span style="font-family: Arial, Helvetica, sans-serif;">tb_article")</span> public class Article{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @ManyToOne(cascade = {CascadeType.PERSIST},fetch = FetchType.EAGER) @JoinColumn(name = "type_id") Private Type type; //在article表總產生1個type_id字段,援用type表中的id字段 @Column(columnDefinition = "text") private String content; private String name; //setter、getter方法略 }
<class name="Type" table="tb_type"> <id name="id" column="id"> <generator class="native"> </id> <property name="name"/> </class> <class name="Article" table="tb_article"> <id name="id" column="id"> <generator class="native"> </id> <property name="name"/> <property name="content"/> <many-to-one name = "type" column = "type_id" cascade = "persist" lazy="false" not-found="ignore"> </ many-to-one > </class>
雙邊多對1、1對多
//“1"方 @Entity @Table(name = "tb_class") public class Clazz{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; //使用反向配置(@ManyToOne不存在該屬性),雙邊關系中,控制權1般交給多方,定義在被具有方,指向具有方,具有方能夠級聯地保護被具有方的關系。因此這里沒有配置數據庫的外鍵,而只配置了1個mappedBy屬性,告知Hibernate,配置信息要到Student類的“clazz"屬性中找 @OneToMany(mappedBy = "clazz") private List<Student> students; //setter、getter方法略 } //“多"方 @Entity @Table(name = "tb_student") public class Student{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @ManyToOne(cascade = {CascadeType.PERSIST},fetch = FetchType.EAGER) @JoinColumn(name = "class_id") Private Clazz clazz; //在student表總產生1個class_id字段,援用class表中的id字段 private String sex; private String name; //setter、getter方法略 }
<class name="Clazz" table="tb_class"> <id name="id" column="id"> <generator class="native"> </id> <property name="name"/> <bag name="students" inverse="true" cascade="all"> <key column="class_id"/> <one-to-many class="com.clf.hibernate.bean.Student"/> </bag> </class> <class name="Student" table="tb_student"> <id name="id" column="id"> <generator class="native"> </id> <property name="name"/> <property name="sex"/> <many-to-one name = "clazz" column = "class_id" cascade = "all" > </ many-to-one > </class>
單邊1對1
有兩種策略可以實現1對1的關聯映照主鍵關聯:即讓兩個對象具有相同的主鍵值,以表明它們之間的逐一對應的關系;數據庫表不會有額外的字段來保護它們之間的關系,僅通過表的主鍵來關聯。唯1外鍵關聯:外鍵關聯,本來是用于多對1的配置,但是如果加上唯1的限制以后,也能夠用來表示1對1關聯關系。唯1外鍵關聯策略@Entity public class IdCard { private int id; private String cardNo; @Id @GeneratedValue public int getId() {return id;} //setter、getter略 } @Entity public class Person { private IdCard idCard;//援用IdCard對象 private String name; @Id @GeneratedValue private int id; @OneToOne @JoinColumn(name="idCard") private IdCard idCard; //援用IdCard對象 private String name; //setter、getter略 }
<class name="com.clf.hibernate.IdCard" table="t_idcard"> <id name="id" column="id"> <generator class="native"/> </id> <property name="cardNo"/> </class> <class name="com.clf.hibernate.Person" table="t_person"> <id name="id" column="id"> <generator class="native"/> </id> <property name="name"/> <!--在多的1端(當前Person1端),加入1個外鍵(當前為idCard)指向1的1端(當前IdCard),但多對1關聯映照字段是可以重復的,所以需要加入1個唯1條件unique="true",這樣就能夠此字段唯1了。--> <many-to-one name="idCard" unique="true"/> </class>
主鍵關聯策略IdCart正常注解
@Entity public class Person { private IdCard idCard;//援用IdCard對象 private String name; @Id @GeneratedValue private int id; @OneToOne @PrimaryKeyJoinColumn //注解主鍵關聯映照 private IdCard idCard; //援用IdCard對象 private String name; //setter、getter略 }
<class name="com.clf.hibernate.IdCard" table="t_idcard"> <id name="id" column="id"> <generator class="native"/> </id> <property name="cardNo"/> </class> <class name="com.clf.hibernate.Person" table="t_person"> <id name="id" column="id"> <!--主鍵不是自己生成的,而是作為1個外鍵,所以使用foreign生成策略。foreign:使用另外1個相干聯的對象的標識符,通常和<one-to-one>聯合起來使用。再使用元素<param>的屬性值指定相干聯對象(這里Person相干聯的對象為idCard,則標識符為idCard的id)為了能夠在加載person數據同時加載IdCard數據,所以需要使用1個標簽<one-to-one>來設置這個功能。 --> <generator class="foreign"> <!-- 元素<param>屬性name的值是固定為property --> <param name="property">idCard</param> </generator> </id> <property name="name"/> <!--表示如何加載它的援用對象(這里援用對象就指idCard這里的name值是idCard),同時也說是1對1的關系。 默許方式是根據主鍵加載(把person中的主鍵取出再到IdCard中來取相干IdCard數據。) 我們也說過此主鍵也作為1個外鍵援用 了IdCard,所以需要加1個數據庫限制(外鍵束縛)constrained="true" --> <one-to-one name="idCard" constrained="true"/> </class>
聯合主鍵關聯(Annotation方式)實現上聯合主鍵的原理同唯1外鍵關聯-單向1樣,只是使用的是@JoinColumns,而不是@JoinColumn,實體類注解以下:@OneToOne @JoinColumns( { @JoinColumn(name="personId", referencedColumnName="id"), @JoinColumn(name="personName", referencedColumnName="name") } ) private Person person;
注意:@JoinColumns注解聯合主鍵1對1聯系,然后再使用@JoinColumn來注解當前表中的外鍵字段名,并指定關聯哪一個字段,使用referencedColumnName指定哪一個字段的名稱
雙邊1對1
凡是雙向關聯,必設mappedBy唯1外鍵關聯策略@Entity public class IdCard { private String cardNo; @Id @GeneratedValue private int id; @OneToOne(mappedBy="idCard") private Person person; //setter、getter略 } @Entity public class Person { private IdCard idCard;//援用IdCard對象 private String name; @Id @GeneratedValue private int id; @OneToOne @JoinColumn(name="idCard") //為idCard對象指定外鍵 private IdCard idCard; //援用IdCard對象 private String name; //setter、getter略 }
<class name="com.clf.hibernate.IdCard" table="t_idcard"> <id name="id" column="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person" property-ref="idCard"/> </class> <!-- 1對1 唯1外鍵 關聯映照 雙向 需要在另外一端(當前IdCard),添加<one-to-one>標簽,唆使hibernate如何加載其關聯對象(或援用對象),默許根據主鍵加載(加載person),外鍵關聯映照中,由于兩個實體采取的是person的外鍵來保護的關系,所以不能指定主鍵加載person,而要根據person的外鍵加載,所以采取以下映照方式: <one-to-one>標簽:告知hibernate如何加載其關聯對象 property-ref屬性:是根據哪一個字段進行比較加載數據 --> <class name="com.clf.hibernate.Person" table="t_person"> <id name="id" column="id"> <generator class="native"/> </id> <property name="name"/> <!--在多的1端(當前Person1端),加入1個外鍵(當前為idCard)指向1的1端(當前IdCard),但多對1關聯映照字段是可以重復的,所以需要加入1個唯1條件unique="true",這樣就能夠此字段唯1了。--> <many-to-one name="idCard" unique="true"/> </class>
主鍵關聯策略@Entity public class IdCard { private String cardNo; @Id @GeneratedValue private int id; @OneToOne(mappedBy="idCard") private Person person; //setter、getter略 } @Entity public class Person { private IdCard idCard;//援用IdCard對象 private String name; @Id @GeneratedValue private int id; @OneToOne @PrimaryKeyJoinColumn //注解主鍵關聯映照 private IdCard idCard; //援用IdCard對象 private String name; //setter、getter略 }
<class name="com.clf.hibernate.IdCard" table="t_idcard"> <id name="id" column="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person"/> </class> <class name="com.clf.hibernate.Person" table="t_person"> <id name="id" column="id"> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <property name="name"/> <one-to-one name="idCard" constrained="true"/> </class>
單邊多對多
@Entity public class User { private int id; private String name; private Set<User> roles = new HashSet<User>();// Role對象的集合 @Id @GeneratedValue public int getId() {return id;} @ManyToMany @JoinTable(name="u_r",//使用@JoinTable標簽的name屬性注解第3方表名稱 joinColumns={@JoinColumn(name="userId")}, //使用joinColumns屬性來注解當前實體類在第3方表中的字段名稱并指向該對象 inverseJoinColumns={@JoinColumn(name="roleId")} //使用inverseJoinColumns屬性來注解當前實體類持有援用對象在第3方表中的字段名稱并指向被援用對象表 ) public Set<User> getRoles() {return roles; }
Role實體正常注解
Role映照文件:<class name="com.clf.hibernate.Role" table="t_role"> <id name="id"> <generator class="native"/> </id> <property name="name" column="name"/> </class> User映照文件: <class name="com.clf.hibernate.User" table="t_user"> <id name="id"column="id"> <generator class="native"/> </id> <property name="name"/> <!--使用<set>標簽映照集合(set),標簽中的name值為對象屬性名(集合roles),而使用table屬性是用于生成第3方表名稱,例:table="t_user_role",但是第3方面中的字段是自動加入的,作為外鍵分別指向其它表。 所以表<key>標簽設置,例:<key column="userid"/>,意思是:在第3方表(t_user_role)中加入1個外鍵并且指向當前的映照實體類所對應的表(t_user).使用<many-to-many>來指定此映照集合所對象的類(實例類),并且使用column屬性加入1個外鍵指向Role實體類所對應的表(t_role) --> <set name="roles" table="t_user_role"> <key column="userid"/> <many-to-many class="com.clf.hibernate.Role" column="roleid"/> </set> </class>
雙邊多對多
User實體類的注解與單邊多對多1樣
Role實體類注解也非常的簡單:使用@ManyToMany注解,并使用mappedBy屬性指定援用對象持有自己的的屬性名@Entity public class Role { private int id; private String name; private Set<User> users = new HashSet<User>(); @Id @GeneratedValue public int getId() {return id; } @ManyToMany(mappedBy="roles") public Set<User> getUsers() {return users;} public voidsetUsers(Set<User> users) {this.users = users; }
<class name="com.clf.hibernate.User" table="t_user"> <id name="id"column="id"> <generator class="native"/> </id> <property name="name"/> <set name="roles" table="t_user_role"> <key column="userid"/> <many-to-many class="com.clf.hibernate.Role" column="roleid"/> </set> </class> <class name="com.clf.hibernate.Role" table="t_role"> <id name="id"> <generator class="native"/> </id> <property name="name" column="name"/> <set name="users" table="t_user_role"order-by="userid"> <key column="roleid"/> <many-to-many class="com.clf.hibernate.User" column="userid"/> </set> </class>
component(組件)關聯映照
例如有以下兩個實體類:用戶與員工,二者存在很多相同的字段,但是二者有不可以是同1個類,這樣在實體類中每次都要輸入很多信息,現在把其中共有部份抽取出來成為1個類,然后在用戶、員工對象中援用就能夠值對象沒有標識,而實體對象具有標識,值對象屬于某1個實體,使用它重復使用率提升,而且更清析。以上關系的映照稱為component(組件)關聯映照在hibernate中,component是某個實體的邏輯組成部份,它與實體的根本區分是沒有oid,component可以成為是值對象(DDD)。采取component映照的好處:它實現了對象模型的細粒度劃分,層次會更加分明,復用率會更高。<class name="com.clf.hibernate.User" table="t_user"> <id name="id" column="id"> <generator class="native"/> </id> <property name="name" column="name"/> <component name="contact"> <property name="email"/> <property name="address"/> <property name="zipCode"/> <property name="contactTel"/> </component> </class>
@Entity public class User { private int id; private String name; private Contact contact;//值對象的援用 @Id @GeneratedValue public int getId() { return id;} @Embedded//用于注解組件映照,表示嵌入對象的映照 public Contact getContact() {return contact;} public void setContact(Contactcontact) {this.contact = contact;}
Contact類是值對象,不是實體對象,是屬于實體類的某1部份,因此沒有映照文件
Contact值對象:public class Contact { private String email; private String address; private String zipCode; private String contactTel; //setter、getter略 }
繼承關聯映照
繼承映照:就是把類的繼承關系映照到數據庫里(首先正確的存儲,再正確的加載數據)繼承關聯映照的分類:單表繼承:每棵類繼承樹使用1個表(table per class hierarchy)具體表繼承:每一個子類1個表(table per subclass)類表繼承:每一個具體類1個表(table per concrete class)(有1些限制)
下面用1個實例來講明3種繼承關系的用法和區分:動物Animal有3個基本屬性,然后有1個Pig繼承了它并擴大了1個屬性,還有1個Brid也繼承了并且擴大了1個屬性
Animal實體類:public class Animal { private int id; private String name; private boolean sex; public int getId() {return id; } public void setId(int id) { this.id = id;} public String getName() {return name;} public void setName(Stringname) {this.name = name;} public boolean isSex() {return sex;} public void setSex(boolean sex) {this.sex = sex;} }
Pig實體類:public class Pig extends Animal { private int weight; public int getWeight() {return weight;} public void setWeight(int weight) {this.weight = weight;} }
Bird實體類:public class Bird extends Animal { private int height; public int getHeight() {return height;} public void setHeight(int height) {this.height = height;} }
單表繼承把所有的屬性都要存儲表中,目前最少需要5個字段,另外需要加入1個標識字段(表示哪一個具體的子類)其中:①、id:表主鍵②、name:動物的姓名,所有的動物都有③、sex:動物的性別,所有的動物都有④、weight:只有豬才有⑤、height:只有鳥才有⑥、type:表示動物的類型;P表示豬;B表示鳥<class name="Animal" table="t_animal" lazy="false"> <id name="id"> <generator class="native"/> </id> <discriminator column="type" type="string"/> <property name="name"/> <property name="sex"/> <subclass name="Pig" discriminator-value="P"> <property name="weight"/> </subclass> <subclass name="Bird" discriminator-value="B"> <property name="height"/> </subclass> </class>
父類用普通的<class>標簽定義在父類中定義1個discriminator,即指定這個辨別的字段的名稱和類型,如:<discriminator column="XXX" type="string"/>子類使用<subclass>標簽定義,在定義subclass的時候,需要注意以下幾點:Subclass標簽的name屬性是子類的全路徑名在Subclass標簽中,用discriminator-value屬性來標明本子類的discriminator字段(用來辨別不同類的字段) 的值Subclass標簽,既可以被class標簽所包括(這類包括關系正是表明了類之間的繼承關系),也能夠與class標 簽平行。 當subclass標簽的定義與class標簽平行的時候,需要在subclass標簽中,添加extends屬性,里面的值 是父類的全路徑名稱。子類的其它屬性,像普通類1樣,定義在subclass標簽的內部。
annotation注解父類中注解以下:使用@Inheritance注解為繼承映照,再使用strategy屬性來指定繼承映照的方式strategy有3個值:InheritanceType.SINGLE_TABLE 單表繼承InheritanceType.TABLE_PER_CLASS 類表繼承InheritanceType.JOINED 具體表繼承再使用@DiscriminatorColumn注意標識字段的字段名,及字段類型在類中使用@DiscriminatorValue來注解標識字段的值@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn( name="discriminator", discriminatorType=DiscriminatorType.STRING) @DiscriminatorValue("type") public class Animal {……}
繼承類中注解以下:只需要使用@DiscriminatorValue來注解標識字段的值
具體表繼承每一個類映照成1個表(table per subclass),所以Animal也映照成1張表(t_animal),表中字段為實體類屬性而pig子類也需要映照成1張表(t_pid),但為了與父類聯系需要加入1個外鍵(pidid)指向父類映照成的表(t_animal),字段為子類的擴大屬性。Bird子類一樣也映照成1張表(t_bird),也加入1個外鍵(birdid)指向父類映照成的表(t_animal),字段為子類的擴大屬性。<class name="com.clf.hibernate.Animal" table="t_animal"> <id name="id"column="id"><!-- 映照主鍵 --> <generator class="native"/> </id> <property name="name"/><!-- 映照普通屬性 --> <property name="sex"/> <!--joined-subclass標簽:每一個類映照成1個表 --> <joined-subclass name="com.clf.hibernate.Pig" table="t_pig"> <!-- <key>標簽:會在相應的表(當前映照的表)里,加入1個外鍵 , 參照指向當前類的父類(當前Class標簽對象的表(t_animal))--> <key column="pigid"/> <property name="weight"/> </joined-subclass> <joined-subclass name="com.clf.hibernate.Bird" table="t_bird"> <key column="birdid"/> <property name="height"/> </joined-subclass> </class>
這類策略是使用joined-subclass標簽來定義子類的。父類、子類,每一個類都對應1張數據庫表。在父類對應的數據庫表中,實際上會存儲所有的記錄,包括父類和子類的記錄;在子類對應的數據庫表中,這個表只定義了子類中所獨有的屬性映照的字段。子類與父類,通過相同的主鍵值來關聯。實現這類策略的時候,有以下步驟:父類用普通的<class>標簽定義便可父類不再需要定義discriminator字段子類用<joined-subclass>標簽定義,在定義joined-subclass的時候,需要注意以下幾點:Joined-subclass標簽的name屬性是子類的全路徑名Joined-subclass標簽需要包括1個key標簽,這個標簽指定了子類和父類之間是通過哪一個字段來關聯的。如:<key column="PARENT_KEY_ID"/>,這里的column,實際上就是父類的主鍵對應的映照字段名稱。Joined-subclass標簽,既可以被class標簽所包括(這類包括關系正是表明了類之間的繼承關系),也能夠與class標簽平行。 當Joined-subclass標簽的定義與class標簽平行的時候,需要在Joined-subclass標簽中,添加extends屬性,里面的值是父類的全路徑名稱。子類的其它屬性,像普通類1樣,定義在joined-subclass標簽的內部。
annotation注解由于子類生成的表需要援用父類生成的表,所以只需要在父類設置具體表繼承映照就能夠了,其它子類只需要使用@Entity注解就能夠了@Entity @Inheritance(strategy=InheritanceType.JOINED) public class Animal {……}
具體表繼承效力沒有單表繼承高,但是單表繼承會出現過剩的庸于字段,具體表層次分明
類表繼承每一個具體類(Pig、Brid)映照成1個表(table per concrete class)(有1些限制)<class name="com.clf.hibernate.Animal" table="t_animal"> <id name="id"column="id"><!-- 映照主鍵 --> <generator class="assigned"/><!-- 每一個具體類映照1個表主鍵生成策略不可以使用native --> </id> <property name="name"/><!-- 映照普通屬性 --> <property name="sex"/> <!--使用<union-subclass>標簽來映照"每一個具體類映照成1張表"的映照關系,實現上上面的表t_animal雖然映照到數據庫中,但它沒有任何作用。 --> <union-subclass name="com.clf.hibernate.Pig" table="t_pig"> <property name="weight"/> </union-subclass> <union-subclass name="com.clf.hibernate.Bird" table="t_bird"> <property name="height"/> </union-subclass> </class>
如果不想t_animal存在(由于它沒有實際的作用),可以設置<class>標簽中的abstract="true"(抽象表),這樣在導出至數據庫時,就不會生成t_animal表了這類策略是使用union-subclass標簽來定義子類的。每一個子類對應1張表,而且這個表的信息是完備的,即包括了所有從父類繼承下來的屬性映照的字段(這就是它跟joined-subclass的不同的地方,joined-subclass定義的子類的表,只包括子類特有屬性映照的字段)。實現這類策略的時候,有以下步驟:父類用普通<class>標簽定義便可子類用<union-subclass>標簽定義,在定義union-subclass的時候,需要注意以下幾點:Union-subclass標簽不再需要包括key標簽(與joined-subclass不同)Union-subclass標簽,既可以被class標簽所包括(這類包括關系正是表明了類之間的繼承關系),也能夠與class標簽平行。 當Union-subclass標簽的定義與class標簽平行的時候,需要在Union-subclass標簽中,添加extends屬性,里面的值是父類的全路徑名稱。子類的其它屬性,像普通類1樣,定義在Union-subclass標簽的內部。這個時候,雖然在union-subclass里面定義的只有子類的屬性,但是由于它繼承了父類,所以,不需要定義其它的屬性,在映照到數據庫表的時候,仍然包括了父類的所有屬性的映照字段。注意:在保存對象的時候id是不能重復的(不能使用自增生成主鍵)
annotation注解只需要對父類進行注解就能夠了,由于子類表的ID是不可以重復,所以1般的主鍵生成策略已不適應了,只有表主鍵生成策略。首先使用@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)來注解繼承映照,并且使用具體表繼承方式,使用@TableGenerator來申明1個表主鍵生成策略再在主鍵上@GeneratedValue(generator="t_gen", strategy=GenerationType.TABLE)來注解生成策略為表生成策略,并且指定表生成策略的名稱繼承類只需要使用@Entity進行注解就能夠了@Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) @TableGenerator( name="t_gen", table="t_gen_table", pkColumnName="t_pk", valueColumnName="t_value", pkColumnValue="person_pk", initialValue=1, allocationSize=1 )
3種繼承關聯映照的區分:第1種:它把所有的數據都存入1個表中,優點:效力好(操作的就是1個表);缺點:存在庸于字段,如果將庸于字段設置為非空,則就沒法存入數據;第2種:層次分明,缺點:效力不好(表間存在關聯表)第3種:主鍵字段不可以設置為自增主鍵生成策略。