位置:首頁 > Java技術 > JPA教學 > JPA高級映射

JPA高級映射

JPA是一種發布使用Java規範的庫。因此,它支持所有的麵向對象的概念實體,持久性。到現在為止,我們已經完成了對象關係映射的基本知識。本章將完成對象和關係單位之間的高級映射。

繼承策略

繼承是任何麵向對象語言的核心理念,因此我們可以用實體之間的繼承關係和策略。JPA支持三種類型的繼承策略:SINGLE_TABLE,JOINED_TABLE和TABLE_PER_CONCRETE_CLASS。

讓我們考慮一個例子。下圖顯示了三個等級,即Staff, TeachingStaff, and NonTeachingStaff和他們之間的關係。

Inheritance Strategy

在上麵的圖中,員工是一個實體,而TeachingStaff和NonTeachingStaff是工作人員的子實體。在這裡,我們將使用上麵的例子來演示繼承的全部三個策略。

單一表策略

單表策略采取所有類的字段(包括超級亞類),並將它們映射成稱為SINGLE_TABLE策略一個表。這裡的鑒彆值起著區分在一個表中三個實體的值的關鍵作用。

讓我們考慮上麵的例子。TeachingStaff和NonTeachingStaff是Staff的子類。按照繼承的概念,一個子類繼承其超類中的屬性。因此sid和sname屬於TeachingStaff和NonTeachingStaff 字段。創建JPA項目。在這個項目中的所有模塊,如下所示:

創建實體

創建一個名為“src”(源)在“com.yiibai.eclipselink.entity'包下。創建一個名為Staff.java新的Java類。工作人員實體類如下所示:

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

創建Staff類的一個子類叫TeachingStaff.java在com.yiibai.eclipselink.entity包下。TeachingStaff 實體類如下所示:

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

創建Staff 的一個子類(類)類叫NonTeachingStaff.java 在 com.yiibai.eclipselink.entity 包下。NonTeachingStaff實體類如下所示:

package com.yiibai.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文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
       <class>com.yiibai.eclipselink.entity.Staff</class>
   	<class>com.yiibai.eclipselink.entity.NonTeachingStaff</class>
   	<class>com.yiibai.eclipselink.entity.TeachingStaff</class>
   	<properties>
   		<property name="javax.persistence.jdbc.url" 
                            value="jdbc:mysql://localhost:3306/jpadb"/>
   		<property name="javax.persistence.jdbc.user" value="root"/>
   		<property name="javax.persistence.jdbc.password" 
                            value="root"/>
   		<property name="javax.persistence.jdbc.driver" 
                            value="com.mysql.jdbc.Driver"/>
   		<property name="eclipselink.logging.level" value="FINE"/>
   		<property name="eclipselink.ddl-generation" 
                            value="create-tables"/>
   	</properties>
   </persistence-unit>
</persistence>

服務類

服務類業務組件的實現部分。創建com.yiibai.eclipselink.service“包在'src”下。

創建一個給定的包下名為SaveClient.java用來存儲Staff,TeachingStaff和NonTeachingStaff類字段類。SaveClient類如下所示:

package com.yiibai.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.yiibai.eclipselink.entity.NonTeachingStaff;
import com.yiibai.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    

最後,會得到一個包含所有三個類字段鑒彆列命名類型(字段)一個表。

注冊策略表

連接表的策略是共享引用的列包含唯一值的加入表並進行便捷事務。讓我們考慮與上述相同的例子。

創建JPA項目。所有工程的模塊如下所示。

創建實體

在“src”下創建一個名為 com.yiibai.eclipselink.entity' 的包。創建一個名為Staff.java新的Java類。Staff 實體類如下所示:

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

創建Staff類的一個子類叫TeachingStaff.java在com.yiibai.eclipselink.entity包下。TeachingStaff 實體類如下所示:

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

創建Staff的一個子類(類)類叫NonTeachingStaff.java在com.yiibai.eclipselink.entity包下。NonTeachingStaff實體類如下所示:

package com.yiibai.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文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
   <class>com.yiibai.eclipselink.entity.Staff</class>
   <class>com.yiibai.eclipselink.entity.NonTeachingStaff</class>
   <class>com.yiibai.eclipselink.entity.TeachingStaff</class>
   	<properties>
   		<property name="javax.persistence.jdbc.url" 
                            value="jdbc:mysql://localhost:3306/jpadb"/>
   		<property name="javax.persistence.jdbc.user" value="root"/>
   		<property name="javax.persistence.jdbc.password" 
                            value="root"/>
   		<property name="javax.persistence.jdbc.driver" 
                            value="com.mysql.jdbc.Driver"/>
   		<property name="eclipselink.logging.level" value="FINE"/>
   		<property name="eclipselink.ddl-generation" 
                            value="create-tables"/>
   	</properties>
   </persistence-unit>
</persistence>

服務類

服務類業務組件的實現部分。在src下創建一個包com.yiibai.eclipselink.service“。

創建一個名為SaveClient.java給定的包來存儲Staff ,TeachingStaff,NonTeachingStaff類來存儲字段。然後SaveClient類如下所示:

package com.yiibai.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.yiibai.eclipselink.entity.NonTeachingStaff;
import com.yiibai.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表將被創建,但它會包含空值。Staff 表的字段值必須同時由TeachingStaff和NonTeachingStaff表共享。

讓我們考慮與上述相同的例子。

創建實體

在src下創建一個名為“com.yiibai.eclipselink.entity'的包。創建一個名為Staff.java為一個新的Java類。Staff實體類如下所示:

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

創建Staff類的一個子類叫TeachingStaff.java 在com.yiibai.eclipselink.entity包下。該TeachingStaff實體類如下所示:

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

創建Staff 的一個子類(類)類叫NonTeachingStaff.java在com.yiibai.eclipselink.entity包下。NonTeachingStaff實體類如下所示:

package com.yiibai.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文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
   <class>com.yiibai.eclipselink.entity.Staff</class>
   <class>com.yiibai.eclipselink.entity.NonTeachingStaff</class>
   <class>com.yiibai.eclipselink.entity.TeachingStaff</class>
   	<properties>
   		<property name="javax.persistence.jdbc.url" 
                            value="jdbc:mysql://localhost:3306/jpadb"/>
   		<property name="javax.persistence.jdbc.user" value="root"/>
   		<property name="javax.persistence.jdbc.password" 
                            value="root"/>
   		<property name="javax.persistence.jdbc.driver" 
                            value="com.mysql.jdbc.Driver"/>
   		<property name="eclipselink.logging.level" value="FINE"/>
   		<property name="eclipselink.ddl-generation" 
                            value="create-tables"/>
   		</properties>
   </persistence-unit>
</persistence>

服務類

服務類業務組件的實現部分。在src下創建一個包com.yiibai.eclipselink.service“。

創建一個給定的包下名為SaveClient.java用來存儲Staff,TeachingStaff和NonTeachingStaff 類字段類。該SaveClient類如下所示:

package com.yiibai.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.yiibai.eclipselink.entity.NonTeachingStaff;
import com.yiibai.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

上表TeachingStaff包含Staff和TeachingStaff實體字段。

NonTeachingStaff的結果顯示如下:

Sid Areaexpertise Sname
3 Accounts Satish
4 Office Admin Krishna

上表NonTeachingStaff包含Staff和NonTeachingStaff實體字段。