JPA是一个随Java规范发布的库.因此,它支持实体持久性的所有面向对象的概念.到目前为止,我们已经完成了对象关系映射的基础知识.本章将指导您完成对象和关系实体之间的高级映射.
继承策略
继承是面向对象语言的核心概念,因此我们可以使用实体之间的继承关系或策略. JPA支持三种类型的继承策略,例如SINGLE_TABLE,JOINED_TABLE和TABLE_PER_CONCRETE_CLASS.
让我们考虑一下Staff,TeachingStaff,NonTeachingStaff类及其关系的示例如下:
在上图中,Staff是一个实体,TeachingStaff和NonTeachingStaff是工作人员的子实体.在这里,我们将在所有三种继承策略中讨论上述示例.
单表策略
单表策略采用所有类字段(均为超级和子类)并将它们映射到一个称为SINGLE_TABLE策略的表中.这里鉴别器值在区分一个表中三个实体的值时起着关键作用.
让我们考虑上面的例子,TeachingStaff和NonTeachingStaff是类Staff的子类.提醒继承的概念(是一种通过子类继承超类属性的机制),因此sid,sname是属于TeachingStaff和NonTeachingStaff的字段.创建一个JPA项目.该项目的所有模块如下:
创建实体
创建一个名为'com.it1352.eclipselink.entity'的包 'src'包下.在给定的包下创建一个名为 Staff.java 的新java类. Staff实体类如下所示:
package com.it1352.eclipselink.entity; import java.io.Serializable;import javax.persistence.DiscriminatorColumn;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Inheritance;import javax.persistence.InheritanceType;import javax.persistence.Table;@Entity@Table@Inheritance( strategy = InheritanceType.SINGLE_TABLE )@DiscriminatorColumn( name = "type" )public class Staff implements Serializable { @Id @GeneratedValue( strategy = GenerationType.AUTO ) private int sid; private String sname; public Staff( int sid, String sname ) { super( ); this.sid = sid; this.sname = sname; } public Staff( ) { super( ); } public int getSid( ) { return sid; } public void setSid( int sid ) { this.sid = sid; } public String getSname( ) { return sname; } public void setSname( String sname ) { this.sname = sname; }}
在上面的代码 @DescriminatorColumn 中指定字段名称(类型)并且它的值显示剩余的(Teaching和NonTeachingStaff)字段.
创建名为 TeachingStaff.java 在 com.it1352.eclipselink.entity 包下. TeachingStaff Entity类如下所示:
package com.it1352.eclipselink.entity; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue(value ="TS")公共类TeachingStaff扩展员工{私人字符串资格; private String subjectexpertise; public TeachingStaff(int sid,String sname, String qualification,String subjectexpertise){ super(sid,sname); this.qualification = qualified; this.subjectexpertise = subjectexpertise; } public TeachingStaff(){ super(); } public String getQualification(){返回资格; } public void setQualification(String qualification){ this.qualification = qualification; } public String getSubjectexpertise(){ return subjectexpertise; } public void setSubjectexpertise(String subjectexpertise){ this.subjectexpertise = subjectexpertise; } }
创建名为 NonTeachingStaff.java 的Staff类的子类(类) com.it1352.eclipselink.entity 包. NonTeachingStaff Entity类如下所示:
package com.it1352.eclipselink.entity; import javax.persistence.DiscriminatorValue;import javax.persistence.Entity;@Entity@DiscriminatorValue( value="TS" )public class TeachingStaff extends Staff { private String qualification; private String subjectexpertise; public TeachingStaff( int sid, String sname, String qualification,String subjectexpertise ) { super( sid, sname ); this.qualification = qualification; this.subjectexpertise = subjectexpertise; } public TeachingStaff( ) { super( ); } public String getQualification( ){ return qualification; } public void setQualification( String qualification ){ this.qualification = qualification; } public String getSubjectexpertise( ) { return subjectexpertise; } public void setSubjectexpertise( String subjectexpertise ){ this.subjectexpertise = subjectexpertise; }}
Persistence.xml
Persistence.xml文件包含配置信息数据库和实体类的注册信息. xml文件如下所示:
com.IT屋.eclipselink.entity.Staff com.IT屋.eclipselink.entity.NonTeachingStaff com.IT屋.eclipselink.entity.TeachingStaff
服务类
服务类是业务组件的实现部分.在名为'com.it1352.eclipselink.service'的'src'包下创建一个包.
创建一个名为SaveClient的类给定包下的.java存储Staff,TeachingStaff和NonTeachingStaff类字段. SaveClient类如下所示:
package com.it1352.eclipselink.service; import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import com.it1352.eclipselink.entity.NonTeachingStaff;import com.it1352.eclipselink.entity.TeachingStaff;public class SaveClient { public static void main( String[ ] args ) { EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" ); EntityManager entitymanager = emfactory.createEntityManager( ); entitymanager.getTransaction( ).begin( ); //Teaching staff entity TeachingStaff ts1=new TeachingStaff(1,"Gopal","MSc MEd","Maths"); TeachingStaff ts2=new TeachingStaff(2, "Manisha", "BSc BEd", "English"); //Non-Teaching Staff entity NonTeachingStaff nts1=new NonTeachingStaff(3, "Satish", "Accounts"); NonTeachingStaff nts2=new NonTeachingStaff(4, "Krishna", "Office Admin"); //storing all entities entitymanager.persist(ts1); entitymanager.persist(ts2); entitymanager.persist(nts1); entitymanager.persist(nts2); entitymanager.getTransaction().commit(); entitymanager.close(); emfactory.close(); }}
编译和执行上述程序后,您将在Eclipse IDE的控制台面板中收到通知.检查MySQL工作台的输出.表格格式的输出如下所示:
Sid | 类型 | Sname | Areaexpertise | 资格 | Subjectexpertise |
---|---|---|---|---|---|
1 | TS | Gopal | MSC MED | Maths | |
2 | TS | Manisha | BSC BED | English | |
3 | NS | Satish | Accounts | ||
4 | NS | Krishna | Office Admin |
最后,您将获得包含所有三个类的字段的单个表,并且与名为的标识符列不同'(字段).
加入表策略
连接表策略是共享引用的列,该列包含连接表的唯一值并进行简单的事务处理.让我们考虑与上面相同的例子.
创建一个JPA项目.所有项目模块如下所示:
创建实体
创建一个名为'com.it1352.eclipselink.entity'的包/b>在'src'包下.在给定的包下创建一个名为 Staff.java 的新java类. Staff实体类如下所示:
package com.it1352.eclipselink.entity; import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Inheritance;import javax.persistence.InheritanceType;import javax.persistence.Table;@Entity@Table@Inheritance( strategy = InheritanceType.JOINED )public class Staff implements Serializable { @Id @GeneratedValue( strategy = GenerationType.AUTO ) private int sid; private String sname; public Staff( int sid, String sname ) { super( ); this.sid = sid; this.sname = sname; } public Staff( ) { super( ); } public int getSid( ) { return sid; } public void setSid( int sid ) { this.sid = sid; } public String getSname( ) { return sname; } public void setSname( String sname ) { this.sname = sname; }}
创建名为 TeachingStaff.java 的Staff类的子类(类) com.it1352.eclipselink.entity 包. TeachingStaff Entity类如下所示:
package com.it1352.eclipselink.entity; import javax.persistence.DiscriminatorValue;import javax.persistence.Entity;@Entity@PrimaryKeyJoinColumn(referencedColumnName="sid")public class TeachingStaff extends Staff { private String qualification; private String subjectexpertise; public TeachingStaff( int sid, String sname, String qualification,String subjectexpertise ) { super( sid, sname ); this.qualification = qualification; this.subjectexpertise = subjectexpertise; } public TeachingStaff( ) { super( ); } public String getQualification( ){ return qualification; } public void setQualification( String qualification ){ this.qualification = qualification; } public String getSubjectexpertise( ) { return subjectexpertise; } public void setSubjectexpertise( String subjectexpertise ){ this.subjectexpertise = subjectexpertise; }}
创建名为 NonTeachingStaff.java 的Staff类的子类(类) com.it1352.eclipselink.entity 包. NonTeachingStaff Entity类如下所示:
package com.it1352.eclipselink.entity; import javax.persistence.DiscriminatorValue;import javax.persistence.Entity;@Entity@PrimaryKeyJoinColumn(referencedColumnName="sid")public class NonTeachingStaff extends Staff { private String areaexpertise; public NonTeachingStaff( int sid, String sname, String areaexpertise ) { super( sid, sname ); this.areaexpertise = areaexpertise; } public NonTeachingStaff( ) { super( ); } public String getAreaexpertise( ) { return areaexpertise; } public void setAreaexpertise( String areaexpertise ) { this.areaexpertise = areaexpertise; }}
Persistence.xml
Persistence.xml文件包含配置信息数据库和实体类的注册信息. xml文件如下所示:
com.IT屋.eclipselink.entity.Staff com.IT屋.eclipselink.entity.NonTeachingStaff com.IT屋.eclipselink.entity.TeachingStaff
服务类
服务类是业务组件的实现部分.在名为'com.it1352.eclipselink.service'的'src'包下创建一个包.
创建一个名为SaveClient的类给定包下的.java存储Staff,TeachingStaff和NonTeachingStaff类字段.然后SaveClient类如下:
package com.it1352.eclipselink.service; import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import com.IT屋.eclipselink.entity.NonTeachingStaff;import com.IT屋.eclipselink.entity.TeachingStaff;public class SaveClient { public static void main( String[ ] args ) { EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" ); EntityManager entitymanager = emfactory.createEntityManager( ); entitymanager.getTransaction( ).begin( ); //Teaching staff entity TeachingStaff ts1 = new TeachingStaff(1,"Gopal","MSc MEd","Maths"); TeachingStaff ts2 = new TeachingStaff(2, "Manisha", "BSc BEd", "English"); //Non-Teaching Staff entity NonTeachingStaff nts1 = new NonTeachingStaff(3, "Satish", "Accounts"); NonTeachingStaff nts2 = new NonTeachingStaff(4, "Krishna", "Office Admin"); //storing all entities entitymanager.persist(ts1); entitymanager.persist(ts2); entitymanager.persist(nts1); entitymanager.persist(nts2); entitymanager.getTransaction().commit(); entitymanager.close(); emfactory.close(); }}
编译和执行上述程序后,您将在Eclipse IDE的控制台面板中收到通知.对于输出检查MySQL工作台如下:
这里创建了三个表,表格格式的 staff 表的结果如下所示:
Sid | Dtype | Sname |
---|---|---|
1 | TeachingStaff | Gopal |
2 | TeachingStaff | Manisha |
3 | NonTeachingStaff | Satish |
4 | NonTeachingStaff | Krishna |
表格中 TeachingStaff 表的结果格式如下所示:
Sid | 资格 | Subjectexpertise |
---|---|---|
1 | MSC MED | Maths |
2 | BSC BED | English |
在上表中,sid是外键(参考字段表格员工表)表格格式的 NonTeachingStaff 表的结果如下所示:
Sid | Areaexpertise |
---|---|
3 | Accounts |
4 | Office Admin |
最后,分别使用字段创建三个表,并且所有三个表共享SID字段.在员工表中,SID是主键,在剩余(TeachingStaff和NonTeachingStaff)表中,SID是外键.
每类策略表
每班表策略是为每个子实体创建一个表.将创建staff表,但它将包含空记录. Staff表的字段值必须由TeachingStaff和NonTeachingStaff表共享.
让我们考虑与上面相同的示例.该项目的所有模块如下所示:
创建实体
创建名为'com.it1352.eclipselink.entity的包'在'src'包下.在给定的包下创建一个名为 Staff.java 的新java类. Staff实体类如下所示:
package com.it1352.eclipselink.entity; import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Inheritance;import javax.persistence.InheritanceType;import javax.persistence.Table;@Entity@Table@Inheritance( strategy = InheritanceType.TABLE_PER_CLASS )public class Staff implements Serializable { @Id @GeneratedValue( strategy = GenerationType.AUTO ) private int sid; private String sname; public Staff( int sid, String sname ) { super( ); this.sid = sid; this.sname = sname; } public Staff( ) { super( ); } public int getSid( ) { return sid; } public void setSid( int sid ) { this.sid = sid; } public String getSname( ) { return sname; } public void setSname( String sname ) { this.sname = sname; }}
创建名为 TeachingStaff.java 的Staff类的子类(类) com.it1352.eclipselink.entity 包. TeachingStaff Entity类如下所示:
package com.it1352.eclipselink.entity; import javax.persistence.DiscriminatorValue;import javax.persistence.Entity;@Entitypublic class TeachingStaff extends Staff { private String qualification; private String subjectexpertise; public TeachingStaff( int sid, String sname, String qualification, String subjectexpertise ) { super( sid, sname ); this.qualification = qualification; this.subjectexpertise = subjectexpertise; } public TeachingStaff( ) { super( ); } public String getQualification( ){ return qualification; } public void setQualification( String qualification ) { this.qualification = qualification; } public String getSubjectexpertise( ) { return subjectexpertise; } public void setSubjectexpertise( String subjectexpertise ){ this.subjectexpertise = subjectexpertise; }}
创建名为 NonTeachingStaff.java 的Staff类的子类(类) com.it1352.eclipselink.entity 包. NonTeachingStaff Entity类如下所示:
package com.it1352.eclipselink.entity; import javax.persistence.DiscriminatorValue;import javax.persistence.Entity;@Entitypublic class NonTeachingStaff extends Staff { private String areaexpertise; public NonTeachingStaff( int sid, String sname, String areaexpertise ) { super( sid, sname ); this.areaexpertise = areaexpertise; } public NonTeachingStaff( ) { super( ); } public String getAreaexpertise( ) { return areaexpertise; } public void setAreaexpertise( String areaexpertise ) { this.areaexpertise = areaexpertise; }}
Persistence.xml
Persistence.xml文件包含配置信息数据库和实体类的注册信息. xml文件如下所示:
com.IT屋.eclipselink.entity.Staff com.IT屋.eclipselink.entity.NonTeachingStaff com.IT屋.eclipselink.entity.TeachingStaff
服务类
服务类是业务组件的实现部分.在名为'com.it1352.eclipselink.service'的'src'包下创建一个包.
创建一个名为
package com.it1352.eclipselink.service; import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import com.IT屋.eclipselink.entity.NonTeachingStaff;import com.IT屋.eclipselink.entity.TeachingStaff;public class SaveClient { public static void main( String[ ] args ) { EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" ); EntityManager entitymanager = emfactory.createEntityManager( ); entitymanager.getTransaction( ).begin( ); //Teaching staff entity TeachingStaff ts1 = new TeachingStaff(1,"Gopal","MSc MEd","Maths"); TeachingStaff ts2 = new TeachingStaff(2, "Manisha", "BSc BEd", "English"); //Non-Teaching Staff entity NonTeachingStaff nts1 = new NonTeachingStaff(3, "Satish", "Accounts"); NonTeachingStaff nts2 = new NonTeachingStaff(4, "Krishna", "Office Admin"); //storing all entities entitymanager.persist(ts1); entitymanager.persist(ts2); entitymanager.persist(nts1); entitymanager.persist(nts2); entitymanager.getTransaction().commit(); entitymanager.close(); emfactory.close(); }}
编译和执行上述程序后,您将在Eclipse IDE的控制台面板中收到通知.对于输出,请按如下方式检查MySQL工作台:
这里创建了三个表, Staff 表包含空记录.
表格格式的 TeachingStaff 的结果显示如下:
Sid | 资格 | Sname | Subjectexpertise |
---|---|---|---|
1 | MSC MED | Gopal | Maths |
2 | BSC BED | Manisha | English |
上表TeachingStaff包含Staff和TeachingStaff实体的字段.
表格格式的 NonTeachingStaff 的结果如下所示:
Sid | Areaexpertise | Sname |
---|---|---|
3 | 账户 | Satish |
4 | Office Admin | Krishna |
上表NonTeachingStaff包含Staff和NonTeachingStaff实体的字段.