La jerarquía de herencia se puede ver fácilmente en la tabla de la base de datos. En Hibernate tenemos tres estrategias diferentes disponibles para el mapeo de herencia
- Tabla por jerarquía
- Tabla por clase de hormigón
- Tabla por subclase
La jerarquía se puede ver esquemáticamente fácilmente.
En este artículo, veamos acerca de la tabla por jerarquía usando XML. También se puede hacer usando anotaciones. Aquí toda la jerarquía está siendo mapeada por una sola tabla. Se crea una columna discriminadora (diferenciadora) en la tabla para identificar la clase. Tomemos una muestra entre el trabajador regular y el trabajador por contrato que se asignan desde el trabajador
Proyecto de ejemplo
Estructura de la tabla MySQL
create table worker( workerId int auto_increment, workerName varchar(25), salary float, additionalBenefits int, pricePerHour float, contractPeriod varchar(25), Primary key (workerId) );
La tabla MySQL llamada ‘trabajador’ se crea con las columnas necesarias. Al ver los nombres de las columnas, podemos llegar a saber que workerId y workerName deberían estar disponibles en la clase Main Worker. salario y beneficios adicionales serían para RegularWorker. pricePerHour y contractPeriod serían para ContractWorker.
Estructura del proyecto:
Como este es el proyecto maven, agreguemos pom.xml
XML
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Inheritence</groupId> <artifactId>Inheritence</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <resources> <resource> <directory>src</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> </resources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <release>9</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.4.15.Final</version> </dependency> <!-- As we are connecting with MySQL, this is needed --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> </dependencies> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> </project>
Como todas las columnas se especifican en una sola tabla, deben distinguirse mediante una columna discriminadora. Se especifica en el archivo hbm. Veamos worker.hbm.xml
trabajador.hbm.xml
XML
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 5.3//EN" "http://hibernate.sourceforge.net/hibernate-mapping-5.3.dtd"> <hibernate-mapping> <!-- Referring to Worker bean --> <class name="com.gfg.hierarchy.Worker" table="worker" discriminator-value="worker"> <id name="workerId"> <generator class="increment"></generator> </id> <!-- As all columns are kept in the same table, we need to have a separate column named "type". It should inform about the type of worker. Here it can be Worker/RegularWorker/ContractWorker --> <discriminator column="type" type="string"></discriminator> <property name="workerName"></property> <!-- RegularWorker is inherited from Worker and hence it should be denoted with subclass and its discriminator-value="regularworker" --> <subclass name="com.gfg.hierarchy.RegularWorker" discriminator-value="regularworker"> <property name="salary"></property> <property name="additionalBenefits"></property> </subclass> <!-- ContractWorker is inherited from Worker and hence it should be denoted with subclass and its discriminator-value="contractworker" --> <subclass name="com.gfg.hierarchy.ContractWorker" discriminator-value="contractworker"> <property name="pricePerHour"></property> <property name="contractPeriod"></property> </subclass> </class> </hibernate-mapping>
Estamos usando MYSQL y, por lo tanto, esas configuraciones deben especificarse en hibernate.cfg.xml
hibernate.cfg.xml
XML
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- As we are connecting mysql, those driver classes, database name, username and password are specified Please change the information as per your requirement --> <property name="hbm2ddl.auto">update</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/geeksforgeeks?serverTimezone=UTC</property> <property name="connection.username">root</property> <property name="connection.password">admin</property> <!-- We are going to connect worker.hbm.xml which has the table information about worker which is present in mysql --> <mapping resource="worker.hbm.xml" /> </session-factory> </hibernate-configuration>
Veamos las clases de bean equivalentes.
Trabajador.java
Java
public class Worker { // Only the columns required for Worker is specified // As RegularWorker and ContractWorker are extended // from this, those required columns // are specified in those tables private int workerId; private String workerName; public int getWorkerId() { return workerId; } public void setWorkerId(int workerId) { this.workerId = workerId; } public String getWorkerName() { return workerName; } public void setWorkerName(String workerName) { this.workerName = workerName; } }
RegularWorker.java
Java
public class RegularWorker extends Worker { // We are specifying only the columns // required for RegularWorker // Hence salary and additionalBenefits // are specified here private float salary; private int additionalBenefits; public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } public int getAdditionalBenefits() { return additionalBenefits; } public void setAdditionalBenefits(int additionalBenefits) { this.additionalBenefits = additionalBenefits; } }
ContractWorker.java
Java
public class ContractWorker extends Worker{ // only the columns required for // ContractWorker are specified here private float pricePerHour; private String contractPeriod; public float getPricePerHour() { return pricePerHour; } public void setpricePerHour(float pricePerHour) { this.pricePerHour = pricePerHour; } public String getContractPeriod() { return contractPeriod; } public void setContractPeriod(String contractPeriod) { this.contractPeriod = contractPeriod; } }
El archivo worker.hbm.xml es el archivo clave muy importante y para la «Tabla por jerarquía», la columna discriminadora es el elemento esencial.
TablePerHierarchyWayOfStoringData.java
Java
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class TablePerHierarchyWayOfStoringData { public static void main(String[] args) { StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build(); Metadata metaData=new MetadataSources(standardServiceRegistry).getMetadataBuilder().build(); SessionFactory factory=metaData.getSessionFactoryBuilder().build(); Session session=factory.openSession(); Transaction transaction=session.beginTransaction(); // This will indicate for the Worker class Worker worker=new Worker(); worker.setWorkerName("Rachel Green"); // This will indicate for the RegularWorker class RegularWorker regularWorker=new RegularWorker(); regularWorker.setWorkerName("Ross"); regularWorker.setSalary(100000); regularWorker.setAdditionalBenefits(50); // This will indicate for the ContractWorker class ContractWorker contractWorker=new ContractWorker(); contractWorker.setWorkerName("Joey Tribbiani"); contractWorker.setpricePerHour(5000); contractWorker.setContractPeriod("25 hours"); session.persist(worker); session.persist(regularWorker); session.persist(contractWorker); transaction.commit(); session.close(); System.out.println("success. We can see 3 records got inserted in worker table and type is the discriminator column"); } }
Ejecución del programa y su salida.
Podemos verificar lo mismo consultando los datos de la base de datos de la tabla de trabajadores. Al ejecutar el código anterior, se insertan 3 registros diferentes. El flujo sigue como la tabla por jerarquía y, por lo tanto, todos los datos se insertarán en una sola tabla. En este ejemplo, use «trabajador» como nombre de tabla y «tipo» como columna discriminadora, y debajo está la salida.
Además, la herencia se puede ver a través de la clase Table Per Concrete (las tablas se crean según la clase) y Table Per Subclass (las tablas se crean según la clase pero están relacionadas por la clave externa).
Publicación traducida automáticamente
Artículo escrito por priyarajtt y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA