JPA - Mappature avanzate

JPA è una libreria rilasciata con specifica Java. Pertanto, supporta tutti i concetti orientati agli oggetti per la persistenza dell'entità. Fino ad ora abbiamo finito con le basi della mappatura relazionale degli oggetti. Questo capitolo ti guida attraverso le mappature avanzate tra oggetti ed entità relazionali.

Strategie di ereditarietà

L'ereditarietà è il concetto centrale del linguaggio orientato agli oggetti, quindi possiamo usare relazioni o strategie di ereditarietà tra entità. JPA supporta tre tipi di strategie di ereditarietà come SINGLE_TABLE, JOINED_TABLE e TABLE_PER_CONCRETE_CLASS.

Consideriamo un esempio di classi Staff, TeachingStaff, NonTeachingStaff e le loro relazioni come segue:

Nel diagramma mostrato sopra, Staff è un'entità e TeachingStaff e NonTeachingStaff sono le sotto entità di Staff. Qui discuteremo l'esempio sopra in tutte e tre le strategie di ereditarietà.

Strategia a tavolo unico

La strategia a tabella singola prende tutti i campi delle classi (sia super che sottoclassi) e li mappa in un'unica tabella nota come strategia SINGLE_TABLE. In questo caso il valore del discriminatore gioca un ruolo chiave nel differenziare i valori di tre entità in una tabella.

Consideriamo l'esempio precedente, TeachingStaff e NonTeachingStaff sono le sottoclassi della classe Staff. Ricorda il concetto di ereditarietà (è un meccanismo per ereditare le proprietà della super classe per sottoclasse) e quindi sid, sname sono i campi che appartengono sia a TeachingStaff che a NonTeachingStaff. Crea un progetto JPA. Tutti i moduli di questo progetto come segue:

Creazione di entità

Crea un pacchetto denominato ‘com.tutorialspoint.eclipselink.entity’ sotto ‘src’pacchetto. Crea una nuova classe java denominataStaff.javasotto dato pacchetto. La classe dell'entità Staff viene mostrata come segue:

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

Nel codice sopra @DescriminatorColumn specifica il nome del campo (type) ei valori di esso mostrano i campi rimanenti (Teaching e NonTeachingStaff).

Crea una sottoclasse (classe) nella classe Staff denominata TeachingStaff.java sotto il com.tutorialspoint.eclipselink.entitypacchetto. La classe TeachingStaff Entity è mostrata come segue:

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

Crea una sottoclasse (classe) nella classe Staff denominata NonTeachingStaff.java sotto il com.tutorialspoint.eclipselink.entitypacchetto. La classe NonTeachingStaff Entity è mostrata come segue:

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

Il file Persistence.xml contiene le informazioni di configurazione del database e le informazioni di registrazione delle classi di entità. Il file xml viene mostrato come segue:

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

Le classi di servizio sono la parte di implementazione del componente aziendale. Crea un pacchetto in‘src’ pacchetto denominato ‘com.tutorialspoint.eclipselink.service’.

Crea una classe denominata SaveClient.java nel pacchetto specificato per archiviare i campi delle classi Staff, TeachingStaff e NonTeachingStaff. La classe SaveClient è mostrata come segue:

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

Dopo la compilazione e l'esecuzione del programma di cui sopra riceverai le notifiche nel pannello della console di Eclipse IDE. Controlla il workbench di MySQL per l'output. L'output in formato tabulare è mostrato come segue:

Sid genere Sname Areaexpertise Qualificazione Competenza soggettiva
1 TS Gopal MSC MED Matematica
2 TS Manisha LETTO BSC Inglese
3 NS Satish Conti
4 NS Krishna Amministratore di Office

Alla fine otterrai una singola tabella che contiene tutti e tre i campi della classe e differisce con la colonna del discriminatore denominata ‘Type’ (campo).

Strategia tavolo unito

La strategia della tabella unita consiste nel condividere la colonna di riferimento che contiene valori univoci per unirsi alla tabella ed effettuare transazioni facili. Consideriamo lo stesso esempio di cui sopra.

Crea un progetto JPA. Tutti i moduli del progetto riportati di seguito:

Creazione di entità

Crea un pacchetto denominato ‘com.tutorialspoint.eclipselink.entity’ sotto ‘src’pacchetto. Crea una nuova classe java denominataStaff.javasotto dato pacchetto. La classe dell'entità Staff viene mostrata come segue:

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

Crea una sottoclasse (classe) nella classe Staff denominata TeachingStaff.java sotto il com.tutorialspoint.eclipselink.entitypacchetto. La classe TeachingStaff Entity è mostrata come segue:

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

Crea una sottoclasse (classe) nella classe Staff denominata NonTeachingStaff.java sotto il com.tutorialspoint.eclipselink.entitypacchetto. La classe NonTeachingStaff Entity è mostrata come segue:

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

Il file Persistence.xml contiene le informazioni di configurazione del database e le informazioni di registrazione delle classi di entità. Il file xml viene mostrato come segue:

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

Le classi di servizio sono la parte di implementazione del componente aziendale. Crea un pacchetto in‘src’ pacchetto denominato ‘com.tutorialspoint.eclipselink.service’.

Crea una classe denominata SaveClient.java nel pacchetto specificato per archiviare i campi delle classi Staff, TeachingStaff e NonTeachingStaff. Quindi classe SaveClient come segue:

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

Dopo la compilazione e l'esecuzione del programma di cui sopra riceverai le notifiche nel pannello della console di Eclipse IDE. Per l'output, controlla il workbench MySQL come segue:

Qui vengono create tre tabelle e il risultato di staff tabella in un formato tabulare è mostrata come segue:

Sid Dtype Sname
1 Personale docente Gopal
2 Personale docente Manisha
3 NonTeachingStaff Satish
4 NonTeachingStaff Krishna

Il risultato di TeachingStaff tabella in un formato tabulare è mostrata come segue:

Sid Qualificazione Competenza soggettiva
1 MSC MED Matematica
2 LETTO BSC Inglese

Nella tabella sopra sid è la chiave esterna (tabella del personale del modulo del campo di riferimento) Il risultato di NonTeachingStaff tabella in formato tabulare è mostrata come segue:

Sid Areaexpertise
3 Conti
4 Amministratore di Office

Infine le tre tabelle vengono create utilizzando rispettivamente i rispettivi campi e il campo SID è condiviso da tutte e tre le tabelle. Nella tabella staff SID è la chiave primaria, nelle restanti tabelle (TeachingStaff e NonTeachingStaff) SID è la chiave esterna.

Tabella per strategia di classe

La strategia della tabella per classe consiste nel creare una tabella per ogni sottoentità. La tabella del personale verrà creata ma conterrà record nulli. I valori dei campi della tabella Staff devono essere condivisi dalle tabelle TeachingStaff e NonTeachingStaff.

Consideriamo lo stesso esempio di cui sopra. Tutti i moduli di questo progetto sono mostrati come segue:

Creazione di entità

Crea un pacchetto denominato ‘com.tutorialspoint.eclipselink.entity’ sotto ‘src’pacchetto. Crea una nuova classe java denominataStaff.javasotto dato pacchetto. La classe dell'entità Staff viene mostrata come segue:

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

Crea una sottoclasse (classe) nella classe Staff denominata TeachingStaff.java sotto il com.tutorialspoint.eclipselink.entitypacchetto. La classe TeachingStaff Entity è mostrata come segue:

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

Crea una sottoclasse (classe) nella classe Staff denominata NonTeachingStaff.java sotto il com.tutorialspoint.eclipselink.entitypacchetto. La classe NonTeachingStaff Entity è mostrata come segue:

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

Il file Persistence.xml contiene le informazioni di configurazione del database e le informazioni di registrazione delle classi di entità. Il file xml viene mostrato come segue:

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

Le classi di servizio sono la parte di implementazione del componente aziendale. Crea un pacchetto in‘src’ pacchetto denominato ‘com.tutorialspoint.eclipselink.service’.

Crea una classe denominata SaveClient.javasotto il pacchetto specificato per memorizzare i campi delle classi Staff, TeachingStaff e NonTeachingStaff. La classe SaveClient è mostrata come segue:

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

Dopo la compilazione e l'esecuzione del programma di cui sopra riceverai le notifiche nel pannello della console di Eclipse IDE. Per l'output, controlla il workbench MySQL come segue:

Qui vengono create le tre tabelle e il file Staff tabella contiene record nulli.

Il risultato di TeachingStaff in un formato tabulare è mostrato come segue:

Sid Qualificazione Sname Competenza soggettiva
1 MSC MED Gopal Matematica
2 LETTO BSC Manisha Inglese

La tabella sopra TeachingStaff contiene i campi delle entità Staff e TeachingStaff.

Il risultato di NonTeachingStaff in un formato tabulare è mostrato come segue:

Sid Areaexpertise Sname
3 Conti Satish
4 Amministratore di Office Krishna

La tabella precedente NonTeachingStaff contiene i campi delle entità Staff e NonTeachingStaff.