JPA-高度なマッピング

JPAは、Java仕様でリリースされたライブラリです。したがって、エンティティの永続性に関するすべてのオブジェクト指向の概念をサポートします。これまで、オブジェクトリレーショナルマッピングの基本はこれで終わりです。この章では、オブジェクトとリレーショナルエンティティ間の高度なマッピングについて説明します。

継承戦略

継承はオブジェクト指向言語のコアコンセプトであるため、エンティティ間の継承関係または戦略を使用できます。JPAは、SINGLE_TABLE、JOINED_TABLE、TABLE_PER_CONCRETE_CLASSなどの3種類の継承戦略をサポートします。

次のように、Staff、TeachingStaff、NonTeachingStaffクラスとそれらの関係の例を考えてみましょう。

上に示した図では、Staffはエンティティであり、TeachingStaffとNonTeachingStaffはStaffのサブエンティティです。ここでは、継承の3つの戦略すべてにおける上記の例について説明します。

シングルテーブル戦略

単一テーブル戦略は、すべてのクラスフィールド(スーパークラスとサブクラスの両方)を取得し、それらをSINGLE_TABLE戦略と呼ばれる単一のテーブルにマップします。ここで、識別子の値は、1つのテーブル内の3つのエンティティの値を区別する上で重要な役割を果たします。

上記の例を考えてみましょう。TeachingStaffとNonTeachingStaffはクラスStaffのサブクラスです。継承の概念(サブクラスごとにスーパークラスのプロパティを継承するメカニズム)を思い出してください。したがって、sid、snameは、TeachingStaffとNonTeachingStaffの両方に属するフィールドです。JPAプロジェクトを作成します。このプロジェクトのすべてのモジュールは次のとおりです。

エンティティの作成

名前の付いたパッケージを作成します ‘com.tutorialspoint.eclipselink.entity’‘src’パッケージ。名前の付いた新しいJavaクラスを作成しますStaff.java与えられたパッケージの下で。スタッフエンティティクラスは次のように表示されます。

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 フィールド名を指定します (type) その値は、残りの(TeachingおよびNonTeachingStaff)フィールドを示します。

名前の付いたStaffクラスのサブクラス(クラス)を作成します TeachingStaff.javacom.tutorialspoint.eclipselink.entityパッケージ。TeachingStaffエンティティクラスは次のように表示されます。

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

名前の付いたStaffクラスのサブクラス(クラス)を作成します NonTeachingStaff.javacom.tutorialspoint.eclipselink.entityパッケージ。NonTeachingStaffエンティティクラスは次のように表示されます。

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ファイルは次のように表示されます。

<?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.tutorialspoint.eclipselink.entity.Staff</class>
      <class>com.tutorialspoint.eclipselink.entity.NonTeachingStaff</class>
      <class>com.tutorialspoint.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.tutorialspoint.eclipselink.service’

指定されたパッケージの下に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();
   }
}

上記のプログラムをコンパイルして実行すると、EclipseIDEのコンソールパネルに通知が表示されます。MySQLワークベンチで出力を確認してください。表形式の出力は次のように表示されます。

シド タイプ Sname Areaexpertise 資格 主題の専門知識
1 TS ゴパル MSC MED 数学
2 TS マニシャ BSCベッド 英語
3 NS サティッシュ アカウント
4 NS クリシュナ オフィス管理者

最後に、3つのクラスのフィールドすべてを含み、名前が付けられた識別子列が異なる単一のテーブルを取得します。 ‘Type’ (フィールド)。

参加テーブル戦略

結合テーブル戦略は、テーブルを結合してトランザクションを容易にするための一意の値を含む参照列を共有することです。上記と同じ例を考えてみましょう。

JPAプロジェクトを作成します。次のように示されているすべてのプロジェクトモジュール:

エンティティの作成

名前の付いたパッケージを作成します ‘com.tutorialspoint.eclipselink.entity’‘src’パッケージ。名前の付いた新しいJavaクラスを作成しますStaff.java与えられたパッケージの下で。スタッフエンティティクラスは次のように表示されます。

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

名前の付いたStaffクラスのサブクラス(クラス)を作成します TeachingStaff.javacom.tutorialspoint.eclipselink.entityパッケージ。TeachingStaffエンティティクラスは次のように表示されます。

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

名前の付いたStaffクラスのサブクラス(クラス)を作成します NonTeachingStaff.javacom.tutorialspoint.eclipselink.entityパッケージ。NonTeachingStaffエンティティクラスは次のように表示されます。

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ファイルは次のように表示されます。

<?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.tutorialspoint.eclipselink.entity.Staff</class>
      <class>com.tutorialspoint.eclipselink.entity.NonTeachingStaff</class>
      <class>com.tutorialspoint.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.tutorialspoint.eclipselink.service’

指定されたパッケージの下に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();
   }
}

上記のプログラムをコンパイルして実行すると、EclipseIDEのコンソールパネルに通知が表示されます。出力については、MySQLワークベンチを次のように確認してください。

ここで3つのテーブルが作成され、 staff 表形式の表は次のように表示されます。

シド Dtype Sname
1 教員 ゴパル
2 教員 マニシャ
3 NonTeachingStaff サティッシュ
4 NonTeachingStaff クリシュナ

結果として TeachingStaff 表形式の表は次のように表示されます。

シド 資格 主題の専門知識
1 MSC MED 数学
2 BSCベッド 英語

上記のテーブルでは、sidは外部キー(スタッフテーブルからの参照フィールド)です。 NonTeachingStaff 表形式の表は次のように表示されます。

シド Areaexpertise
3 アカウント
4 オフィス管理者

最後に、3つのテーブルはそれぞれのフィールドを使用して作成され、SIDフィールドは3つのテーブルすべてで共有されます。スタッフテーブルではSIDが主キーであり、残りの(TeachingStaffおよびNonTeachingStaff)テーブルではSIDが外部キーです。

クラスごとのテーブル戦略

クラスごとのテーブル戦略は、サブエンティティごとにテーブルを作成することです。スタッフテーブルが作成されますが、nullレコードが含まれます。Staffテーブルのフィールド値は、TeachingStaffテーブルとNonTeachingStaffテーブルで共有する必要があります。

上記と同じ例を考えてみましょう。このプロジェクトのすべてのモジュールは次のように示されています。

エンティティの作成

名前の付いたパッケージを作成します ‘com.tutorialspoint.eclipselink.entity’‘src’パッケージ。名前の付いた新しいJavaクラスを作成しますStaff.java与えられたパッケージの下で。スタッフエンティティクラスは次のように表示されます。

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

名前の付いたStaffクラスのサブクラス(クラス)を作成します TeachingStaff.javacom.tutorialspoint.eclipselink.entityパッケージ。TeachingStaffエンティティクラスは次のように表示されます。

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

名前の付いたStaffクラスのサブクラス(クラス)を作成します NonTeachingStaff.javacom.tutorialspoint.eclipselink.entityパッケージ。NonTeachingStaffエンティティクラスは次のように表示されます。

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ファイルは次のように表示されます。

<?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.tutorialspoint.eclipselink.entity.Staff</class>
      <class>com.tutorialspoint.eclipselink.entity.NonTeachingStaff</class>
      <class>com.tutorialspoint.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.tutorialspoint.eclipselink.service’

という名前のクラスを作成します 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();
   }
}

上記のプログラムをコンパイルして実行すると、EclipseIDEのコンソールパネルに通知が表示されます。出力については、MySQLワークベンチを次のように確認してください。

ここで3つのテーブルが作成され、 Staff テーブルにnullレコードが含まれています。

結果として TeachingStaff 表形式で次のように表示されます。

シド 資格 Sname 主題の専門知識
1 MSC MED ゴパル 数学
2 BSCベッド マニシャ 英語

上記のテーブルTeachingStaffには、StaffエンティティとTeachingStaffエンティティの両方のフィールドが含まれています。

結果として NonTeachingStaff 表形式で次のように表示されます。

シド Areaexpertise Sname
3 アカウント サティッシュ
4 オフィス管理者 クリシュナ

上記のテーブルNonTeachingStaffには、StaffエンティティとNonTeachingStaffエンティティの両方のフィールドが含まれています。