Учебники

JPA – Расширенные сопоставления

JPA – это библиотека, выпущенная со спецификацией Java. Следовательно, он поддерживает все объектно-ориентированные концепции для сохранения сущности. До сих пор мы закончили с основами реляционного отображения объектов. В этой главе рассказывается о сложных сопоставлениях между объектами и реляционными сущностями.

Стратегии наследования

Наследование является основной концепцией объектно-ориентированного языка, поэтому мы можем использовать наследственные отношения или стратегии между сущностями. JPA поддерживает три типа стратегий наследования, такие как SINGLE_TABLE, JOINED_TABLE и TABLE_PER_CONCRETE_CLASS.

Давайте рассмотрим пример классов Staff, TeachingStaff, NonTeachingStaff и их взаимосвязей:

Стратегия наследования

На показанной выше диаграмме Staff является сущностью, а TeachingStaff и NonTeachingStaff являются дочерними сущностями Staff. Здесь мы обсудим приведенный выше пример во всех трех стратегиях наследования.

Стратегия единого стола

Стратегия с одной таблицей берет все поля классов (как супер, так и подклассы) и отображает их в одну таблицу, известную как стратегия SINGLE_TABLE. Здесь значение дискриминатора играет ключевую роль в дифференцировании значений трех сущностей в одной таблице.

Давайте рассмотрим приведенный выше пример. 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 указывает имя поля (тип), а в значениях этого поля отображаются оставшиеся (Teaching и NonTeachingStaff) поля.

Создайте подкласс (класс) для класса Staff с именем TeachingStaff.java в пакете com.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.java в пакете com.tutorialspoint.eclipselink.entity . Класс 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();
   }
}

После компиляции и выполнения вышеуказанной программы вы получите уведомления на панели консоли Eclipse IDE. Проверьте MySQL верстак для вывода. Вывод в табличном формате показан следующим образом:

Sid Тип $ name Areaexpertise Квалификация Subjectexpertise
1 TS Гопал MSC MED математика
2 TS Маниша BSC BED английский
3 NS Сатиш Счета
4 NS Кришна Администратор офиса

Наконец, вы получите одну таблицу, которая содержит все три поля класса и отличается от столбца дискриминатора с именем «Тип» (поле).

Стратегия объединенного стола

Стратегия присоединяемой таблицы заключается в том, чтобы совместно использовать ссылочный столбец, содержащий уникальные значения, для присоединения к таблице и выполнения простых транзакций. Давайте рассмотрим тот же пример, что и выше.

Создать проект 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.java в пакете com.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.java в пакете com.tutorialspoint.eclipselink.entity . Класс 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();
   }
}

После компиляции и выполнения вышеуказанной программы вы получите уведомления на панели консоли Eclipse IDE. Для вывода проверьте MySQL Workbench следующим образом:

Здесь создаются три таблицы, и результат таблицы персонала в табличном формате отображается следующим образом:

Sid DTYPE $ name
1 Преподавательский состав Гопал
2 Преподавательский состав Маниша
3 NonTeachingStaff Сатиш
4 NonTeachingStaff Кришна

Результат таблицы TeachingStaff в табличном формате показан ниже:

Sid Квалификация Subjectexpertise
1 MSC MED математика
2 BSC BED английский

В приведенной выше таблице sid – это внешний ключ (таблица персонала формы справочного поля). Результат таблицы NonTeachingStaff в табличном формате показан ниже:

Sid Areaexpertise
3 Счета
4 Администратор офиса

Наконец, три таблицы создаются с использованием их полей соответственно, и поле SID используется всеми тремя таблицами. В таблице персонала SID является первичным ключом, в остальных (TeachingStaff и NonTeachingStaff) таблицах SID является внешним ключом.

Таблица для стратегии класса

Стратегия для каждого класса заключается в создании таблицы для каждого дочернего объекта. Таблица персонала будет создана, но она будет содержать нулевые записи. Значения полей таблицы 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.java в пакете com.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.java в пакете com.tutorialspoint.eclipselink.entity . Класс 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();
   }
}

После компиляции и выполнения вышеуказанной программы вы получите уведомления на панели консоли Eclipse IDE. Для вывода проверьте MySQL Workbench следующим образом:

Здесь создаются три таблицы, а таблица Staff содержит нулевые записи.

Результат TeachingStaff в табличном формате показан ниже:

Sid Квалификация $ name Subjectexpertise
1 MSC MED Гопал математика
2 BSC BED Маниша английский

Приведенная выше таблица TeachingStaff содержит поля сущностей Staff и TeachingStaff.

Результат NonTeachingStaff в табличном формате показан ниже:

Sid Areaexpertise $ name
3 Счета Сатиш
4 Администратор офиса Кришна

Приведенная выше таблица NonTeachingStaff содержит поля сущностей Staff и NonTeachingStaff.