Hibernate – Asignación de mapas ordenados

SortedMap es un mapa que siempre mantiene sus entradas correspondientes en orden de clave ascendente. En Hibernate, usando el elemento <map> y ‘sort’ como ‘natural’ podemos mantener el SortedMap. Veamos eso usando el concepto de relación de uno a muchos. Por ejemplo, para un lenguaje de programación como Java, se escriben muchos libros. Si se sigue SortedMap, los libros se organizan en orden alfabético. Veamos eso a través de un proyecto de muestra.

Proyecto de ejemplo 

Estructura del proyecto:

Project Structure

 

Vamos a crear tablas MySQL.

-- Main table which has languagename like Java
CREATE TABLE `programmingLanguages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `languageName` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
-- Child table that has book details related to a languageId and hence it is referred here
-- Via sortedmapping in hibernate, master detail relationship is getting set
CREATE TABLE `bookDetails` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bookName` varchar(40) DEFAULT NULL,
  `authorName` varchar(30) DEFAULT NULL,
  `languageId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;

Proyecto impulsado por Maven. Veamos el archivo pom.xml.

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>HibernateSortedMapMapping</groupId>
  <artifactId>HibernateSortedMapMapping</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>

Comencemos con las clases de POJO. Como hay dos tablas, tengamos 2 clases POJO cada una para una tabla.

ProgramaciónLanguages.java

Java

import java.util.SortedMap;
 
public class ProgrammingLanguages {
    // data members
    private int id;
    // As we are seeing SortedMap example, let us have the
    // books to be of java.util.SortedMap
    public SortedMap getBooks() { return books; }
    public void setBooks(SortedMap books)
    {
        this.books = books;
    }
    private String languageName;
    private SortedMap books;
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getLanguageName() { return languageName; }
    public void setLanguageName(String languageName)
    {
        this.languageName = languageName;
    }
    // no argument constructor
    public ProgrammingLanguages() {}
    // argument constructor
    public ProgrammingLanguages(String languageName)
    {
        this.languageName = languageName;
    }
}

Libro.java

Java

public class Book implements Comparable<String> {
    private int id;
    private String bookName;
    public int getId() { return id; }
 
    public void setId(int id) { this.id = id; }
 
    public String getBookName() { return bookName; }
 
    public void setBookName(String bookName)
    {
        this.bookName = bookName;
    }
 
    public String getAuthorName() { return authorName; }
 
    public void setAuthorName(String authorName)
    {
        this.authorName = authorName;
    }
 
    private String authorName;
    // argument Constructor
    public Book(String bookName, String authorName)
    {
        this.bookName = bookName;
        this.authorName = authorName;
    }
    // No argument Constructor
    public Book() {}
    // This method has to be implemented as we are using
    // Comparable Sorting is getting followed for SortedMap
    @Override
    public int compareTo(String book)
    {
        if (this == null) {
            return 1;
        }
        else if (book == null) {
            return -1;
        }
        else {
            return this.compareTo(book);
        }
    }
}

Veamos ahora los archivos de configuración.

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>
       
         <!-- This will be helpful to know how the
             data is getting queried in backend -->
         <property name="show_sql">true</property>
         
         <!--  We are going to connect language.hbm.xml and book.hbm.xml
                which has the table information about programmingLanguages
                and book which is present in mysql -->
         <mapping resource="language.hbm.xml"/>
        <mapping resource="book.hbm.xml"/>
       
    </session-factory>
</hibernate-configuration>

En el archivo de configuración principal, se agregan 2 recursos de mapeo. Vamos a verlos

idioma.hbm.xml

XML

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping SYSTEM
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  
<hibernate-mapping>
  
  <!-- Always keep the POJO class name and MySQL table name alike -->
 <class name="com.gfg.sortedmapmapping.pojo.ProgrammingLanguages" table="programminglanguages">
  <id name="id" type="int" column="id">
    <generator class="native"></generator>
  </id>
  
  <property name="languageName" column="languageName" type="string"/>
  
  <!-- For using SortedMap, we have to follow the below syntax
       key column is the connecting column between both the labels
       index column is required  for SortedMap and that is
       not required in the case of bag mapping
       Relationship followed here is one-to-many as one
       language can have multiple books -->
   <map name="books" cascade="all"  sort="natural" >
       <key column="languageId"/>
       <index column="Language_Class"  type="string"/>
       <one-to-many class="com.gfg.sortedmapmapping.pojo.Book"/>
  </map>
  
 </class>
  
</hibernate-mapping>

libro.hbm.xml

XML

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping SYSTEM
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  
<hibernate-mapping>
  
  <class name="com.gfg.sortedmapmapping.pojo.Book" table="bookdetails">
    <id name="id" type="int" column="id">
    <generator class="native"></generator>
    </id>
  
    <property name="bookName" column="bookName" type="string"></property>
    <property name="authorName" column="authorName" type="string"></property>
  
  </class>
  
</hibernate-mapping>

Vayamos a la clase principal que agrega lenguaje de programación y libros a la tabla MySQL y enumera desde allí

SortedMapMappingPatternOfStoringData.java

Java

import com.gfg.sortedmapmapping.pojo.Book;
import com.gfg.sortedmapmapping.pojo.ProgrammingLanguages;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.security.auth.Subject;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
public class SortedMapMappingPatternOfStoringData {
    private static SessionFactory factory;
    public static void main(String[] args)
    {
        try {
            factory = new Configuration()
                          .configure()
                          .buildSessionFactory();
        }
        catch (Throwable ex) {
            System.err.println(
                "Failed to create sessionFactory object."
                + ex);
            throw new ExceptionInInitializerError(ex);
        }
 
        // Let us add Java as programming language and for
        // that effectively 3 books (with author name)
        // details are added
        TreeMap map = new TreeMap();
        map.put("Java1", new Book("J2EE", "Dave Evans"));
        map.put("Java2", new Book("Core Java Volume I",
                                  "Cay S. Horstmann"));
        map.put("Java3",
                new Book("Effective Java", "Joshua Bloch"));
 
        // Create the Language object.
        ProgrammingLanguages language
            = new ProgrammingLanguages("Java");
        language.setBooks(map);
 
        SortedMapMappingPatternOfStoringData
            sortedMapMappingPatternOfStoringData
            = new SortedMapMappingPatternOfStoringData();
        // insert language object.
        Integer languageId
            = sortedMapMappingPatternOfStoringData
                  .addLanguage(language);
 
        // show all Language and book details object.
        sortedMapMappingPatternOfStoringData
            .listLanguageAndBookDetails();
    }
 
    /* Method to add programming languages in the database
     */
    public Integer
    addLanguage(ProgrammingLanguages language)
    {
        Session session = factory.openSession();
        Transaction tx = null;
        Integer languageId = null;
        try {
            tx = session.beginTransaction();
            languageId = (Integer)session.save(language);
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
        return languageId;
    }
 
    /* Method to list all the language and book detail */
    public void listLanguageAndBookDetails()
    {
        Session session = factory.openSession();
        Transaction tx = null;
 
        try {
            tx = session.beginTransaction();
            List programmingLanguages
                = session
                      .createQuery(
                          "FROM ProgrammingLanguages")
                      .list();
            for (Iterator iterator
                 = programmingLanguages.iterator();
                 iterator.hasNext();) {
                ProgrammingLanguages language
                    = (ProgrammingLanguages)iterator.next();
                System.out.print(
                    "Language Name: "
                    + language.getLanguageName());
 
                Map books = language.getBooks();
                System.out.println(
                    "Book Name:"
                    + ((Book)books.get("Java1"))
                          .getBookName());
                System.out.println(
                    "Author Name:"
                    + ((Book)books.get("Java1"))
                          .getAuthorName());
 
                System.out.println(
                    "Book Name:"
                    + ((Book)books.get("Java2"))
                          .getBookName());
                System.out.println(
                    "Author Name:"
                    + ((Book)books.get("Java2"))
                          .getAuthorName());
 
                System.out.println(
                    "Book Name:"
                    + ((Book)books.get("Java3"))
                          .getBookName());
                System.out.println(
                    "Author Name:"
                    + ((Book)books.get("Java3"))
                          .getAuthorName());
            }
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
    }
}

Al ejecutar el proyecto, podemos ver el siguiente resultado en la consola.

Producción:

Output

 

Veamos la explicación de salida en detalle.

Output

 

Output

 

Salida de la tabla MySQL:

MySQL table output

 

Conclusión

En el mapeo ordenado, la columna de índice es imprescindible y también se representa en la salida de MySql. Mientras se almacenan también, de acuerdo con el orden alfabético del nombre del libro, se almacenan en MySQL

Publicación traducida automáticamente

Artículo escrito por priyarajtt y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *