延迟加载与即时加载
例如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,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了。-->
<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种:主键字段不可以设置为自增主键生成策略。