JPA - Mappages avancés

JPA est une bibliothèque publiée avec la spécification Java. Par conséquent, il prend en charge tous les concepts orientés objet pour la persistance des entités. Jusqu'à présent, nous en avons terminé avec les bases du mappage relationnel d'objets. Ce chapitre vous présente les mappages avancés entre les objets et les entités relationnelles.

Stratégies d'héritage

L'héritage est le concept central du langage orienté objet, nous pouvons donc utiliser des relations ou des stratégies d'héritage entre les entités. JPA prend en charge trois types de stratégies d'héritage telles que SINGLE_TABLE, JOINED_TABLE et TABLE_PER_CONCRETE_CLASS.

Prenons un exemple de classes Staff, TeachingStaff, NonTeachingStaff et leurs relations comme suit:

Dans le diagramme ci-dessus, Staff est une entité et TeachingStaff et NonTeachingStaff sont les sous-entités de Staff. Ici, nous discuterons de l'exemple ci-dessus dans les trois stratégies d'héritage.

Stratégie de table unique

La stratégie de table unique prend tous les champs de classes (super et sous-classes) et les mappe en une seule table connue sous le nom de stratégie SINGLE_TABLE. Ici, la valeur du discriminateur joue un rôle clé dans la différenciation des valeurs de trois entités dans une table.

Prenons l'exemple ci-dessus, TeachingStaff et NonTeachingStaff sont les sous-classes du personnel de classe. Rappelons le concept d'héritage (c'est un mécanisme d'héritage des propriétés de super classe par sous-classe) et donc sid, sname sont les champs qui appartiennent à la fois à TeachingStaff et NonTeachingStaff. Créez un projet JPA. Tous les modules de ce projet comme suit:

Créer des entités

Créez un package nommé ‘com.tutorialspoint.eclipselink.entity’ en dessous de ‘src’paquet. Créez une nouvelle classe Java nomméeStaff.javasous le paquet donné. La classe d'entité Staff est présentée comme suit:

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

Dans le code ci-dessus @DescriminatorColumn spécifie le nom du champ (type) et ses valeurs montrent les champs restants (Teaching et NonTeachingStaff).

Créez une sous-classe (classe) dans la classe Staff nommée TeachingStaff.java sous le com.tutorialspoint.eclipselink.entitypaquet. La classe Entité TeachingStaff est représentée comme suit:

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

Créez une sous-classe (classe) dans la classe Staff nommée NonTeachingStaff.java sous le com.tutorialspoint.eclipselink.entitypaquet. La classe d'entité NonTeachingStaff est affichée comme suit:

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

Le fichier Persistence.xml contient les informations de configuration de la base de données et les informations d'enregistrement des classes d'entités. Le fichier xml est affiché comme suit:

<?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>

Classe de service

Les classes de service sont la partie implémentation du composant métier. Créez un package sous‘src’ package nommé ‘com.tutorialspoint.eclipselink.service’.

Créez une classe nommée SaveClient.java sous le package donné pour stocker les champs de classe Staff, TeachingStaff et NonTeachingStaff. La classe SaveClient est présentée comme suit:

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

Après la compilation et l'exécution du programme ci-dessus, vous recevrez des notifications dans le panneau de la console d'Eclipse IDE. Vérifiez le workbench MySQL pour la sortie. La sortie dans un format tabulaire est présentée comme suit:

Sid Type Le nom de Expertise régionale Qualification Expertise en matière
1 TS Gopal MSC MED Mathématiques
2 TS Manisha LIT BSC Anglais
3 NS Satish Comptes
4 NS Krishna Administrateur de bureau

Enfin, vous obtiendrez une seule table qui contient les trois champs de la classe et diffère avec la colonne discriminatrice nommée ‘Type’ (champ).

Stratégie de table jointe

La stratégie de table jointe consiste à partager la colonne référencée qui contient des valeurs uniques pour rejoindre la table et effectuer des transactions faciles. Prenons le même exemple que ci-dessus.

Créez un projet JPA. Tous les modules de projet présentés comme suit:

Créer des entités

Créez un package nommé ‘com.tutorialspoint.eclipselink.entity’ en dessous de ‘src’paquet. Créez une nouvelle classe Java nomméeStaff.javasous le paquet donné. La classe d'entité Staff est présentée comme suit:

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

Créez une sous-classe (classe) dans la classe Staff nommée TeachingStaff.java sous le com.tutorialspoint.eclipselink.entitypaquet. La classe Entité TeachingStaff est représentée comme suit:

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

Créez une sous-classe (classe) dans la classe Staff nommée NonTeachingStaff.java sous le com.tutorialspoint.eclipselink.entitypaquet. La classe d'entité NonTeachingStaff est affichée comme suit:

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

Le fichier Persistence.xml contient les informations de configuration de la base de données et les informations d'enregistrement des classes d'entités. Le fichier xml est affiché comme suit:

<?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>

Classe de service

Les classes de service sont la partie implémentation du composant métier. Créez un package sous‘src’ package nommé ‘com.tutorialspoint.eclipselink.service’.

Créez une classe nommée SaveClient.java sous le package donné pour stocker les champs de classe Staff, TeachingStaff et NonTeachingStaff. Puis classe SaveClient comme suit:

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

Après la compilation et l'exécution du programme ci-dessus, vous recevrez des notifications dans le panneau de la console d'Eclipse IDE. Pour la sortie, vérifiez le workbench MySQL comme suit:

Ici, trois tableaux sont créés et le résultat de staff tableau au format tabulaire est présenté comme suit:

Sid Dtype Le nom de
1 Personnel enseignant Gopal
2 Personnel enseignant Manisha
3 Personnel non enseignant Satish
4 Personnel non enseignant Krishna

Le résultat de TeachingStaff tableau au format tabulaire est présenté comme suit:

Sid Qualification Expertise en matière
1 MSC MED Mathématiques
2 LIT BSC Anglais

Dans le tableau ci-dessus, sid est la clé étrangère (champ de référence du tableau des employés) Le résultat de NonTeachingStaff tableau au format tabulaire est présenté comme suit:

Sid Expertise régionale
3 Comptes
4 Administrateur de bureau

Enfin, les trois tables sont créées à l'aide de leurs champs respectivement et le champ SID est partagé par les trois tables. Dans la table du personnel, le SID est la clé primaire, dans les tables restantes (TeachingStaff et NonTeachingStaff), le SID est la clé étrangère.

Tableau par stratégie de classe

La stratégie de table par classe consiste à créer une table pour chaque sous-entité. La table du personnel sera créée mais elle contiendra des enregistrements nuls. Les valeurs de champ de la table Staff doivent être partagées par les tables TeachingStaff et NonTeachingStaff.

Prenons le même exemple que ci-dessus. Tous les modules de ce projet sont présentés comme suit:

Créer des entités

Créez un package nommé ‘com.tutorialspoint.eclipselink.entity’ en dessous de ‘src’paquet. Créez une nouvelle classe Java nomméeStaff.javasous le paquet donné. La classe d'entité Staff est présentée comme suit:

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

Créez une sous-classe (classe) dans la classe Staff nommée TeachingStaff.java sous le com.tutorialspoint.eclipselink.entitypaquet. La classe Entité TeachingStaff est représentée comme suit:

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

Créez une sous-classe (classe) dans la classe Staff nommée NonTeachingStaff.java sous le com.tutorialspoint.eclipselink.entitypaquet. La classe d'entité NonTeachingStaff est affichée comme suit:

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

Le fichier Persistence.xml contient les informations de configuration de la base de données et les informations d'enregistrement des classes d'entités. Le fichier xml est affiché comme suit:

<?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>

Classe de service

Les classes de service sont la partie implémentation du composant métier. Créez un package sous‘src’ package nommé ‘com.tutorialspoint.eclipselink.service’.

Créez une classe nommée SaveClient.javasous le package donné pour stocker les champs de classe Staff, TeachingStaff et NonTeachingStaff. La classe SaveClient est présentée comme suit:

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

Après la compilation et l'exécution du programme ci-dessus, vous recevrez des notifications dans le panneau de la console d'Eclipse IDE. Pour la sortie, vérifiez MySQL workbench comme suit:

Ici, les trois tableaux sont créés et le Staff La table contient des enregistrements nuls.

Le résultat de TeachingStaff dans un format tabulaire est présenté comme suit:

Sid Qualification Le nom de Expertise en matière
1 MSC MED Gopal Mathématiques
2 LIT BSC Manisha Anglais

Le tableau ci-dessus TeachingStaff contient les champs des entités Staff et TeachingStaff.

Le résultat de NonTeachingStaff dans un format tabulaire est présenté comme suit:

Sid Expertise régionale Le nom de
3 Comptes Satish
4 Administrateur de bureau Krishna

Le tableau ci-dessus NonTeachingStaff contient les champs des entités Staff et NonTeachingStaff.