unidades:04_claves_primarias_y_tipos_datos:03_componentes
Diferencias
Muestra las diferencias entre dos versiones de la página.
— | unidades:04_claves_primarias_y_tipos_datos:03_componentes [2023/04/07 21:26] (actual) – creado - editor externo 127.0.0.1 | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
+ | ====== Componentes ====== | ||
+ | Los componentes permiten que varias clases relacionadas se almacenen en una única tabla de la base de datos. Es similar a la relación //uno a uno// desde el punto de vista de Java pero en la base de datos sólo hay una tabla. | ||
+ | ===== Clases Java ===== | ||
+ | Antes de entrar en cómo se implemente en Hibernate , veamos las clases Java y las tablas que definen la relación. | ||
+ | |||
+ | Para nuestro ejemplo vamos a usar las clases: | ||
+ | |||
+ | * Profesor | ||
+ | * Nombre | ||
+ | |||
+ | <code java 1> | ||
+ | public class Profesor implements Serializable | ||
+ | private int id; | ||
+ | private Nombre nombre; | ||
+ | | ||
+ | public Profesor(){ | ||
+ | } | ||
+ | |||
+ | public Profesor(int id, Nombre nombre) { | ||
+ | this.id = id; | ||
+ | this.nombre=nombre; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public class Nombre implements Serializable { | ||
+ | private String nombre; | ||
+ | private String ape1; | ||
+ | private String ape2; | ||
+ | | ||
+ | public Nombre() { | ||
+ | | ||
+ | } | ||
+ | |||
+ | public Nombre(String nombre, String ape1, String ape2) { | ||
+ | this.nombre = nombre; | ||
+ | this.ape1 = ape1; | ||
+ | this.ape2 = ape2; | ||
+ | } | ||
+ | | ||
+ | public String getNombreCompleto() { | ||
+ | StringBuilder sb=new StringBuilder(); | ||
+ | if ((ape1!=null) && (ape1.trim().length()> | ||
+ | sb.append(ape1); | ||
+ | } | ||
+ | if ((ape2!=null) && (ape2.trim().length()> | ||
+ | if (sb.length()> | ||
+ | sb.append(" | ||
+ | } | ||
+ | sb.append(ape2); | ||
+ | } | ||
+ | if ((nombre!=null) && (nombre.trim().length()> | ||
+ | if (sb.length()> | ||
+ | sb.append("," | ||
+ | } | ||
+ | sb.append(nombre); | ||
+ | } | ||
+ | |||
+ | | ||
+ | return sb.toString(); | ||
+ | } | ||
+ | | ||
+ | public String getIniciales() { | ||
+ | StringBuilder sb=new StringBuilder(); | ||
+ | if ((nombre!=null) && (nombre.trim().length()> | ||
+ | sb.append(nombre.substring(0, | ||
+ | } | ||
+ | if ((ape1!=null) && (ape1.trim().length()> | ||
+ | sb.append(ape1.substring(0, | ||
+ | } | ||
+ | if ((ape2!=null) && (ape2.trim().length()> | ||
+ | sb.append(ape2.substring(0, | ||
+ | } | ||
+ | | ||
+ | return sb.toString().toUpperCase(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | Lo que hemos hecho es extraer las propiedades '' | ||
+ | |||
+ | <note important> | ||
+ | |||
+ | En el siguiente diagrama UML se ve que la relación es desde '' | ||
+ | |||
+ | <uml> | ||
+ | class Profesor | ||
+ | Profesor : int id | ||
+ | |||
+ | |||
+ | |||
+ | class Nombre | ||
+ | Nombre : String nombre | ||
+ | Nombre : String ape1 | ||
+ | Nombre : String ape2 | ||
+ | Nombre : getNombreCompleto() | ||
+ | Nombre : getIniciales() | ||
+ | |||
+ | Profesor " | ||
+ | </ | ||
+ | |||
+ | ===== Tablas ===== | ||
+ | La tabla de base de datos quedaría de la siguiente forma: | ||
+ | |||
+ | <uml> | ||
+ | class Profesor << | ||
+ | Profesor : INTEGER id | ||
+ | Profesor : VARCHAR nombre | ||
+ | Profesor : VARCHAR ape1 | ||
+ | Profesor : VARCHAR ape2 | ||
+ | </ | ||
+ | |||
+ | Podemos apreciar que en el diseño de las tabla de la base de datos no existe ninguna tabla '' | ||
+ | |||
+ | ===== Fichero de mapeo '' | ||
+ | Al persistir las dos clases será necesario un único fichero de persistencia: | ||
+ | * '' | ||
+ | |||
+ | ==== Profesor.hbm.xml ==== | ||
+ | El fichero '' | ||
+ | |||
+ | <code xml 1| Fichero Profesor.hbm.xml> | ||
+ | <?xml version=" | ||
+ | < | ||
+ | < | ||
+ | <class name=" | ||
+ | <id column=" | ||
+ | | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | El fichero básicamente es muy sencillo excepto por el nuevo tag '' | ||
+ | |||
+ | === Tag component === | ||
+ | El tag ''< | ||
+ | * '' | ||
+ | |||
+ | ===== Anotaciones ===== | ||
+ | Para usar anotaciones deberemos modificar el código fuente de las clases Java y **no** usar los ficheros '' | ||
+ | |||
+ | El código fuente de la clase '' | ||
+ | |||
+ | <code java 1| Clase Profesor anotada > | ||
+ | @Entity | ||
+ | @Table(name=" | ||
+ | public class Profesor implements Serializable | ||
+ | | ||
+ | @Id | ||
+ | @Column(name=" | ||
+ | private int id; | ||
+ | @Embedded | ||
+ | private Nombre nombre; | ||
+ | | ||
+ | |||
+ | public Profesor(){ | ||
+ | } | ||
+ | |||
+ | public Profesor(int id, Nombre nombre) { | ||
+ | this.id = id; | ||
+ | this.nombre=nombre; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | En la línea 8 se ha incluido la anotación '' | ||
+ | |||
+ | * **@Embedded**: | ||
+ | |||
+ | La clase Java '' | ||
+ | |||
+ | <code java 1| Clase Nombre anotada > | ||
+ | @Embeddable | ||
+ | public class Nombre implements Serializable { | ||
+ | | ||
+ | @Column(name=" | ||
+ | private String nombre; | ||
+ | | ||
+ | @Column(name=" | ||
+ | private String ape1; | ||
+ | | ||
+ | @Column(name=" | ||
+ | private String ape2; | ||
+ | | ||
+ | public Nombre() { | ||
+ | | ||
+ | } | ||
+ | |||
+ | public Nombre(String nombre, String ape1, String ape2) { | ||
+ | this.nombre = nombre; | ||
+ | this.ape1 = ape1; | ||
+ | this.ape2 = ape2; | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | public String getNombreCompleto() { | ||
+ | StringBuilder sb=new StringBuilder(); | ||
+ | if ((ape1!=null) && (ape1.trim().length()> | ||
+ | sb.append(ape1); | ||
+ | } | ||
+ | if ((ape2!=null) && (ape2.trim().length()> | ||
+ | if (sb.length()> | ||
+ | sb.append(" | ||
+ | } | ||
+ | sb.append(ape2); | ||
+ | } | ||
+ | if ((nombre!=null) && (nombre.trim().length()> | ||
+ | if (sb.length()> | ||
+ | sb.append("," | ||
+ | } | ||
+ | sb.append(nombre); | ||
+ | } | ||
+ | |||
+ | | ||
+ | return sb.toString(); | ||
+ | } | ||
+ | | ||
+ | public String getIniciales() { | ||
+ | StringBuilder sb=new StringBuilder(); | ||
+ | if ((nombre!=null) && (nombre.trim().length()> | ||
+ | sb.append(nombre.substring(0, | ||
+ | } | ||
+ | if ((ape1!=null) && (ape1.trim().length()> | ||
+ | sb.append(ape1.substring(0, | ||
+ | } | ||
+ | if ((ape2!=null) && (ape2.trim().length()> | ||
+ | sb.append(ape2.substring(0, | ||
+ | } | ||
+ | | ||
+ | return sb.toString().toUpperCase(); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | A nivel de clase se ha incluido en la línea 1 el atributo '' | ||
+ | |||
+ | * **@Embeddable**: | ||
+ | ===== Código Java ===== | ||
+ | Ahora que ya tenemos preparadas las clase Java para que puedan persistirse veamos el código necesario para persistirlas. | ||
+ | |||
+ | <code java 1 | Persistiendo la clase Profesor> | ||
+ | Profesor profesor=new Profesor(410, | ||
+ | |||
+ | Session session=sessionFactory.openSession(); | ||
+ | session.beginTransaction(); | ||
+ | |||
+ | session.save(profesor); | ||
+ | |||
+ | session.getTransaction().commit(); | ||
+ | session.close(); | ||
+ | </ | ||
+ | |||
+ | Como podemos ver, el usar componentes no añade ningún tipo de complejidad al código Java que se usa. | ||
+ | |||
+ | ===== Diferencias ===== | ||
+ | Veamos ahora qué diferencias hay entre crear una relación [[unidades: | ||
+ | |||
+ | * En una relación //uno a uno// las 2 clases Java se almacenan en tablas distintas mientras que en un componente lo hace en la misma tabla. | ||
+ | * En una relación //uno a uno// las 2 clases Java deben incluir la referencia a la clave primaria que ambas comparten mientras que en un componente sólo necesita clave primaria la clase // | ||
+ | * En una relación //uno a uno// es posible persistir cualquiera de las 2 clases y se guardará la otra pero en un componente sólo se puede persistir la clase principal y no el componente. |