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под данным пакетом. Класс сущности 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 указывает имя поля (type) и его значения показывают оставшиеся поля (Teaching и NonTeachingStaff).
Создайте подкласс (класс) класса Staff с именем TeachingStaff.java под com.tutorialspoint.eclipselink.entityпакет. Класс TeachingStaff Entity показан следующим образом:
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пакет. Класс 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 показан следующим образом:
<?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 для вывода. Вывод в табличном формате показан следующим образом:
Сид | Тип | Sname | Areaexpertise | Квалификация | Subjectexpertise |
---|---|---|---|---|---|
1 | TS | Гопал | MSC MED | Математика | |
2 | TS | Маниша | BSC КРОВАТЬ | английский | |
3 | NS | Satish | Счета | ||
4 | NS | Кришна | Администратор офиса |
Наконец, вы получите одну таблицу, которая содержит все три поля класса и отличается столбцом дискриминатора с именем ‘Type’ (поле).
Стратегия объединенного стола
Стратегия объединенной таблицы заключается в том, чтобы поделиться ссылочным столбцом, который содержит уникальные значения для объединения в таблицу и упрощения транзакций. Давайте рассмотрим тот же пример, что и выше.
Создайте проект JPA. Все модули проекта показаны следующим образом:
Создание сущностей
Создайте пакет с именем ‘com.tutorialspoint.eclipselink.entity’ под ‘src’пакет. Создайте новый класс Java с именемStaff.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;
}
}
Создайте подкласс (класс) класса Staff с именем TeachingStaff.java под com.tutorialspoint.eclipselink.entityпакет. Класс TeachingStaff Entity показан следующим образом:
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пакет. Класс 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 показан следующим образом:
<?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 следующим образом:
Здесь создаются три таблицы и результат staff Таблица в табличном формате отображается следующим образом:
Сид | Dtype | Sname |
---|---|---|
1 | Преподавательский состав | Гопал |
2 | Преподавательский состав | Маниша |
3 | Неучебный персонал | Satish |
4 | Неучебный персонал | Кришна |
Результат TeachingStaff Таблица в табличном формате отображается следующим образом:
Сид | Квалификация | Subjectexpertise |
---|---|---|
1 | MSC MED | Математика |
2 | BSC КРОВАТЬ | английский |
В приведенной выше таблице sid - это внешний ключ (справочное поле из таблицы сотрудников). NonTeachingStaff Таблица в табличном формате отображается следующим образом:
Сид | Areaexpertise |
---|---|
3 | Счета |
4 | Администратор офиса |
Наконец, три таблицы создаются с использованием своих полей соответственно, и поле SID используется всеми тремя таблицами. В штатном расписании SID является первичным ключом, в остальных (TeachingStaff и NonTeachingStaff) таблицах SID является внешним ключом.
Таблица на класс стратегии
Стратегия «Таблица для каждого класса» заключается в создании таблицы для каждого подобъекта. Штатное расписание будет создано, но оно будет содержать пустые записи. Значения полей таблицы Staff должны использоваться совместно с таблицами TeachingStaff и NonTeachingStaff.
Давайте рассмотрим тот же пример, что и выше. Все модули этого проекта показаны следующим образом:
Создание сущностей
Создайте пакет с именем ‘com.tutorialspoint.eclipselink.entity’ под ‘src’пакет. Создайте новый класс Java с именемStaff.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;
}
}
Создайте подкласс (класс) класса Staff с именем TeachingStaff.java под com.tutorialspoint.eclipselink.entityпакет. Класс TeachingStaff Entity показан следующим образом:
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пакет. Класс 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 показан следующим образом:
<?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 следующим образом:
Здесь созданы три таблицы и Staff таблица содержит пустые записи.
Результат TeachingStaff в табличном формате отображается следующим образом:
Сид | Квалификация | Sname | Subjectexpertise |
---|---|---|---|
1 | MSC MED | Гопал | Математика |
2 | BSC КРОВАТЬ | Маниша | английский |
Приведенная выше таблица TeachingStaff содержит поля сущностей Staff и TeachingStaff.
Результат NonTeachingStaff в табличном формате отображается следующим образом:
Сид | Areaexpertise | Sname |
---|---|---|
3 | Счета | Satish |
4 | Администратор офиса | Кришна |
Приведенная выше таблица NonTeachingStaff содержит поля как объектов Staff, так и NonTeachingStaff.