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.