📜  JPA-高级映射

📅  最后修改于: 2020-11-13 05:06:14             🧑  作者: Mango


JPA是随Java规范一起发布的库。因此,它支持用于实体持久性的所有面向对象的概念。到现在为止,我们已经完成了对象关系映射的基础知识。本章将引导您完成对象与关系实体之间的高级映射。

继承策略

继承是面向对象语言的核心概念,因此我们可以在实体之间使用继承关系或策略。 JPA支持三种类型的继承策略,例如SINGLE_TABLE,JOINED_TABLE和TABLE_PER_CONCRETE_CLASS。

让我们考虑一个职员,TeachingStaff,NonTeachingStaff类及其关系的示例,如下所示:

继承策略

在上面显示的图中,Staff是一个实体,TeachingStaff和NonTeachingStaff是Staff的子实体。在这里,我们将在所有三种继承策略中讨论以上示例。

单表策略

单表策略采用所有类字段(超级类和子类)并将它们向下映射到称为SINGLE_TABLE策略的单个表中。在此,鉴别值在区分一张表中三个实体的值方面起着关键作用。

让我们考虑上面的示例,TeachingStaff和NonTeachingStaff是Staff类的子类。提醒一下继承的概念(一种通过子类继承超类属性的机制),因此sid,sname是属于TeachingStaff和NonTeachingStaff的字段。创建一个JPA项目。该项目的所有模块如下:

创建实体

“ src”包下创建一个名为“ com.tutorialspoint.eclipselink.entity”包。在给定的包下创建一个名为Staff.java的新Java类。 Staff实体类如下所示:

package com.tutorialspoint.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)字段。

com.tutorialspoint.eclipselink.entity包下,创建一个名为TeachingStaff.java的Staff类的子类(类)。教学人员实体类如下所示:

package com.tutorialspoint.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;
   }
}

com.tutorialspoint.eclipselink.entity包下,创建一个名为NonTeachingStaff.java的Staff类的子类(类)。 NonTeachingStaff Entity类如下所示:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue( value = "NS" )

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.tutorialspoint.eclipselink.entity.Staff
      com.tutorialspoint.eclipselink.entity.NonTeachingStaff
      com.tutorialspoint.eclipselink.entity.TeachingStaff
      
      
         
         
         
         
         
         
      
      
   

服务等级

服务类是业务组件的实现部分。在名为“ com.tutorialspoint.eclipselink.service”的“ src”包下创建一个包。

在给定的包下创建一个名为SaveClient.java的类,以存储Staff,TeachingStaff和NonTeachingStaff类字段。 SaveClient类如下所示:

package com.tutorialspoint.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.tutorialspoint.eclipselink.entity.NonTeachingStaff;
import com.tutorialspoint.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 Type Sname Areaexpertise Qualification Subjectexpertise
1 TS Gopal MSC MED Maths
2 TS Manisha BSC BED English
3 NS Satish Accounts
4 NS Krishna Office Admin

最后,您将获得一个包含所有三个类字段的表,并且与名为“ Type” (字段)的区分符列有所不同。

加盟桌策略

联接表策略是共享被引用的列,该列包含用于联接表并简化事务的唯一值。让我们考虑与上述相同的示例。

创建一个JPA项目。所有项目模块如下所示:

创建实体

“ src”包下创建一个名为“ com.tutorialspoint.eclipselink.entity”包。在给定的包下创建一个名为Staff.java的新Java类。 Staff实体类如下所示:

package com.tutorialspoint.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;
   }
}

com.tutorialspoint.eclipselink.entity包下,创建一个名为TeachingStaff.java的Staff类的子类(类)。教学人员实体类如下所示:

package com.tutorialspoint.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;
   }
}

com.tutorialspoint.eclipselink.entity包下,创建一个名为NonTeachingStaff.java的Staff类的子类(类)。 NonTeachingStaff Entity类如下所示:

package com.tutorialspoint.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.tutorialspoint.eclipselink.entity.Staff
      com.tutorialspoint.eclipselink.entity.NonTeachingStaff
      com.tutorialspoint.eclipselink.entity.TeachingStaff
      
      
         
         
         
         
         
         
      
      
   

服务等级

服务类是业务组件的实现部分。在名为“ com.tutorialspoint.eclipselink.service”的“ src”包下创建一个包。

在给定的包下创建一个名为SaveClient.java的类,以存储Staff,TeachingStaff和NonTeachingStaff类字段。然后,SaveClient类如下:

package com.tutorialspoint.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.tutorialspoint.eclipselink.entity.NonTeachingStaff;
import com.tutorialspoint.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 Dtype Sname
1 TeachingStaff Gopal
2 TeachingStaff Manisha
3 NonTeachingStaff Satish
4 NonTeachingStaff Krishna

表格形式的TeachingStaff表的结果如下所示:

Sid Qualification Subjectexpertise
1 MSC MED Maths
2 BSC BED English

在上面的表sid中是外键(表单域职员表的引用字段)表格式的NonTeachingStaff表的结果如下所示:

Sid Areaexpertise
3 Accounts
4 Office Admin

最后,分别使用它们的字段创建三个表,并且所有三个表共享SID字段。在人员表中,SID是主键,在其余(TeachingStaff和NonTeachingStaff)表中,SID是外键。

每课表策略

每类表策略是为每个子实体创建一个表。将创建人员表,但其中将包含空记录。 Staff表的字段值必须由TeachingStaff和NonTeachingStaff表共享。

让我们考虑与上述相同的示例。该项目的所有模块如下所示:

创建实体

“ src”包下创建一个名为“ com.tutorialspoint.eclipselink.entity”包。在给定的包下创建一个名为Staff.java的新Java类。 Staff实体类如下所示:

package com.tutorialspoint.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;
   }
}

com.tutorialspoint.eclipselink.entity包下,创建一个名为TeachingStaff.java的Staff类的子类(类)。教学人员实体类如下所示:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
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;
   }
}

com.tutorialspoint.eclipselink.entity包下,创建一个名为NonTeachingStaff.java的Staff类的子类(类)。 NonTeachingStaff Entity类如下所示:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
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.tutorialspoint.eclipselink.entity.Staff
      com.tutorialspoint.eclipselink.entity.NonTeachingStaff
      com.tutorialspoint.eclipselink.entity.TeachingStaff
      
      
         
         
         
         
         
         
      
      
   

服务等级

服务类是业务组件的实现部分。在名为“ com.tutorialspoint.eclipselink.service”的“ src”包下创建一个包。

在给定的包下创建一个名为SaveClient.java的类,以存储Staff,TeachingStaff和NonTeachingStaff类字段。 SaveClient类如下所示:

package com.tutorialspoint.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.tutorialspoint.eclipselink.entity.NonTeachingStaff;
import com.tutorialspoint.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 Qualification Sname Subjectexpertise
1 MSC MED Gopal Maths
2 BSC BED Manisha English

上表“教学人员”包含“人员”和“教学人员”实体的字段。

表格格式的NonTeachingStaff的结果如下所示:

Sid Areaexpertise Sname
3 Accounts Satish
4 Office Admin Krishna

上表NonTeachingStaff包含Staff和NonTeachingStaff实体的字段。