Está en la página 1de 9

Sesion 4.

Mapeo Objeto-Relacional
IG47/II47. Dise
no y gestion de bases de datos
Martes 1/12/2009 y Jueves 3/12/2009

1.

Objetivos
Ser capaz de crear ficheros de mapeo entre un modelo orientado a objetos y un modelo relacional,
utilizando el modelo de mapeo objetorelacional de Hibernate.
Ser capaz de insertar, actualizar y borrar datos persistentes en una base de datos relacional mediante
un lenguaje orientados a objetos.

2.

Entrega y Evaluaci
on

Para que la realizacion de esta practica forme parte de tu evaluacion deberas realizarla en el aula de
practicas y hacer la entrega al finalizar la sesion subiendo un fichero con las respuestas a trav
es del aula
virtual. Si no puedes asistir a la clase correspondiente, puedes realizar la practica por tu cuenta y entregarla
como muy tarde el viernes 4 de diciembre.
En esta sesion no hay ejercicio adicional.

3.

Mapeo objetorelacional

El mapeo objetorelacional permite convertir los datos utilizados en un lenguaje de programacion orientado a objetos, en datos persistentes en una base de datos relacional, y viceversa.
En esta practica, ademas de utilizar el SGBD MySQL, vamos a trabajar con el lenguaje de programacion
orientado a objetos Java y la biblioteca Hibernate.
Hibernate1 es un conjunto de libreras que permite realizar un mapeo objetorelacional para la plataforma Java (disponible tambien para .Net con el nombre de NHibernate). Para realizar el mapeo, Hibernate
utiliza ficheros XML que permiten establecer las relaciones entre el modelo de objetos y la base de datos
relacional.
1 Hibernate

es software libre, con licencia GNU LGPL. M


as informaci
on en http://www.hibernate.org

4.

Un modelo de datos

El modelo de datos con el que vamos a trabajar consta de tres entidades: asignaturas, profesores y
alumnos. Un profesor puede ser el responsable de una o mas asignaturas, sin embargo las asignaturas solo
pueden tener un profesor responsable. Ademas, un alumno puede estar matriculado en muchas asignaturas
y una asignatura puede tener muchos alumnos. El modelo entidadrelacion y el modelo orientado a objetos
se muestran en la figura 1.

Figura 1. Modelo entidadrelacion frente al orientado a objetos.

5.

Trabajando con Java e Hibernate

En esta sesion vamos a trabajar en Windows. Sin embargo, las herramientas que vamos a utilizar son
multiplataforma. Para trabajar con Java vamos a utilizar en entorno de desarrollo Eclipse 2 .
En el Windows de las aulas Eclipse se encuentra en el men
u de inicio, en el apartado de programas
dentro de la seccion de programacion.
Al lanzar Eclipse se te pide que indiques el directorio de trabajo, esto es, el workspace. Deja el directorio
que aparece por defecto, pero recuerda cual es para utilizarlo despues. Entra en la web del curso en el aula
virtual y descarga en el escritorio el archivo orm.zip que contiene el proyecto con el que vamos a trabajar.
Descomprime en el directorio de trabajo el archivo orm.zip e importalo en el Eclipse. Para saber como
importarlo puedes consultar el documento adicional sobre Eclipse.
La ventana principal de Eclipse debe parecerse a la de la figura 2.
Para que el proyecto se compile correctamente debemos importar varias libreras: Hibernate y JDBC
de Java para MySQL. En el documento adicional veras como importar estas libreras, que deberas descargar
del aula virtual (est
an comprimidas).
El fichero hibernate.cfg.xml contiene la informacion de la configuracion de Hibernate (haciendo doble
click sobre el fichero se abrira en la ventana principal). El contenido es el siguiente:

<?xml version=1.0 encoding=utf-8?>


2 Eclipse

tambi
en es software libre. M
as informaci
on en http://www.eclipse.org/

Figura 1: Figura 2.- Ventana principal de Eclipse con el proyecto cargado

<!DOCTYPE hibernate-configuration PUBLIC


"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://........</property>
<property name="hibernate.connection.username">......</property>
<property name="hibernate.connection.password">......</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Mapping files -->
<mapping resource="Clases/Profesor.hbm.xml"/>
<mapping resource="Clases/Alumno.hbm.xml"/>
<mapping resource="Clases/Asignatura.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Fjate que hemos activado la opcion show sql. De esta manera se mostraran en la consola las sentencias
3

SQL que se van generando.


En los puntos suspensivos es donde deberemos indicar la base de datos, el usuario y la contrase
na,
necesarios para poder hacer la conexion con MySQL.
Un ejemplo de los parametros de la conexion para el alumno alXXXXXX es el siguiente:
<property name="hibernate.connection.url">
jdbc:mysql://db-aules.uji.es/alXXXXXX?ssl=true
</property>
<property name="hibernate.connection.username">alXXXXXX</property>
<property name="hibernate.connection.password">alXXXXXX</property>
Ejercicio 1. Completa el fichero de configuracion con los datos de tu cuenta y tu base de datos de
MySQL. Tu usuario de MySQL, la contrase
na y la base de datos tienen tu nombre de usuario. Abre un
fichero de texto para la entrega y copia y pega en el todo lo que vayas haciendo en los ejercicios.
Conectate a MySQL y comprueba que tu base de datos no contiene ninguna tabla. Para conectarte a
MySQL hazlo desde lynx utilizando putty. En el documento adicional se indica como debes conectarte a
MySQL y algunas ordenes basicas.

6.

Mapeando clases

6.1.

Mapeando clases simples

En primer lugar vamos a mapear las clases a tablas. Para ello cada clase debe tener su propio fichero
de mapeo. Ademas el fichero de mapeo debe encontrarse en el mismo directorio en el que se encuentra la
implementaci
on de la clase que mapea. En nuestro proyecto se encuentran en la carpeta Clases.
El mapeo de clases a la base de datos, y viceversa, se realiza invocando a los metodos getXxxxx y
setXxxxx, siendo xxxxx el nombre de las propiedades de las clases. Debe existir una funcion get y una
funcion set para cada una de las propiedades de la clase (puedes ver como las hemos implementado en las
clases abriendo los ficheros que tienen el nombre de la clase y la estension .java).
Veamos el contenido de mapeo de la clase Profesor, que se encuentra en el fichero Profesor.hbm.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Clases.Profesor" table="profesor">
<id name="nif" column="nif" type="integer">
<generator class="assigned"/>
</id>
<property name="nombre" update="true" insert="true"
type="java.lang.String" column="nombre" />
<property name="apellidos" update="true" insert="true"
type="java.lang.String" column="apellidos"/>
<property name="fechaNacimiento" update="true" insert="true"
type="java.util.Date" column="fecha_nacimiento" />
4

</class>
</hibernate-mapping>
Ejercicio 2. Completa los ficheros de mapeo de las clases Asignatura y Alumno completando lo que aparece
con puntos suspensivos a continuaci
on.
Fichero de mapeo de la clase Asignatura:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Clases.Asignatura" table=".....">
<id name="....." column="codasig" type="java.lang.String">
<generator class="assigned"/>
</id>
<property name="....." update="true" insert="true"
type="java.lang.String" column="....." />
</class>
</hibernate-mapping>
Fichero de mapeo de la clase Alumno:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="....." table="Alumnos">
<id name="nif" column="nif" type="integer">
<generator class="assigned"/>
</id>
<property name="nombre" update="true" insert="true"
type="java.lang.String" column="nombre" />
<property name="....." update="true" insert="true"
type="java.lang.String" column="apellidos"/>
<property name="fechaNacimiento" update="true" insert="true"
type="java.util.Date" column="....." />
</class>
</hibernate-mapping>

Una vez modificados los ficheros de mapeo, vamos a comprobar que funcionan. Para ello vamos a
ejecutar la clase Objetos.java. Antes de hacerlo, abre el fichero y mira el codigo. Aunque no sepas Java, lo
entenderas.
Para ejecutar la clase, selecciona en Eclipse la opcion del men
u run-->Open Run Dialog. En la figura 3
puedes ver que debes indicar en el nombre del proyecto y el nombre de la clase a ejecutar (main class).
Una vez indicados estos, puedes darle a ejecutar (run).
Ejercicio 3. Conectate a MySQL. Recuerda que tu base de datos estaba vaca que contiene ahora?
Quien ha generado las sentencias SQL que han hecho todo eso en tu base de datos?

Figura 3. Ventana de ejecucion de Eclipse.

6.2.

Mapeando relaciones uno a muchos

Cuando trabajamos con bases de datos relacionales, las relaciones entre los objetos son fundamentales.
En este apartado vamos a trabajar con la relacion un profesor puede ser responsable de varias asignaturas.
En el esquema logico de una base de datos relacional, cuando aparece una relacion unoamuchos, lo
que hacemos es a
nadir una clave ajena: la tabla del lado del muchos contiene una clave ajena que hace
referencia a la tabla del lado del uno. Sin embargo, cuando trabajamos con objetos, suele ser la clase de la
parte del uno la que tiene una coleccion de objetos del tipo de la otra clase de la relacion, la del muchos.
Para representar la relacion entre profesores y asignaturas haremos lo mismo. En la clase Profesor.java
crearemos una coleccion para almacenar las asignaturas con sus correspondientes metodos (get y set).
Ademas, deberemos a
nadir un metodo nuevo que permita a
nadir asignaturas a la coleccion de un determinado
objeto.
Ejercicio 4. Modifica los ficheros de mapeo de las clases Profesor y Asignatura para que reflejen la
relacion. A continuaci
on se muestra como deben quedar. No hagas copiar y pegar del pdf, teclea lo que has
de a
nadir y as entender
as como se hace.
6

El fichero de mapeo de la clase Profesor quedara as:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Clases.Profesor" table="profesor">
<id name="nif" column="nif" type="integer">
<generator class="assigned"/>
</id>
<property name="nombre" update="true" insert="true"
type="java.lang.String" column="nombre" />
<property name="apellidos" update="true" insert="true"
type="java.lang.String" column="apellidos"/>
<property name="fechaNacimiento" update="true" insert="true"
type="java.util.Date" column="fecha_nacimiento" />
<set name="asignaturasResponsable" table="Asignaturas">
<key column="profresp"/>
<one-to-many class="Clases.Asignatura"/>
</set>
</class>
</hibernate-mapping>
y el fichero de mapeo de la clase Asignatura quedara as:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Clases.Asignatura" table="asignaturas">
<id name="codasig" column="codasig" type="java.lang.String">
<generator class="assigned"/>
</id>
<property name="nomasig" update="true" insert="true"
type="java.lang.String" column="nomasig" />
<many-to-one name="Profresp" column="profresp" />
</class>
</hibernate-mapping>
La clase ObjetosRelacion.java es practicamente igual a la clase Objetos.java, puedes comprobarlo
mirando el codigo. Ver
as que u
nicamente se a
nade al objeto del profesor las asignaturas de las que es
responsable. Ya has comprobado que la clase Objetos.java ha insertado datos en tu base de datos.
Ejercicio 5. Antes de ejecutar esta clase contesta a esta pregunta crees que se poducira alg
un error en su
ejecucion? Por que?
Ejecuta ahora la clase ObjetosRelacion.java3 y comprueba el resultado. Ha ocurrido lo que esperabas
que sucediera?
Modifica la forma de actualizar los objetos en la clase ObjetosRelacion.java, cambiando la funcion
3 Para

ejecutar esta clase abre el di


alogo de run y cambia el nombre de Objetos por ObjetosRelaci
on.

save(objeto) por saveOrUpdate(objeto) y ejecuta de nuevo la clase ObjetosRelacion.java. Ha funcionado ahora?


Ejercicio 6. Comenta como ha cambiado el esquema de tu base de datos.

6.3.

Mapeando relaciones muchos a muchos

Veamos ahora como se mapea la relacion entre alumno y asignatura, donde una alumno puede estar
matriculado de varias asignaturas y una asignatura puede tener varios alumnos matriculados.
En el esquema logico de una base de datos relacional, ante una relacion muchosamuchos lo que
hacemos es a
nadir una nueva tabla. Si la relacion no tiene atributos, esta tabla tiene como clave primaria,
las dos claves ajenas que referencian a cada una de las tablas que forman parte de la relacion. En este caso,
al programar con orientaci
on a objetos, cada uno de las clases de la relacion debe tener una coleccion de
objetos del tipo de la otra clase de la relacion.
Ejercicio 7. Crees que es necesario crear la tabla de la relacion muchosamuchos? o por el contrario
crees que Hibernate sera capaz de crearla?
Lo primero que vamos a hacer es a
nadir a la clase Alumno la coleccion para almacenar las asignaturas
que esta matriculado, y a la clase Asignatura la coleccion para almacenar los alumnos que estan matriculados
en ella. Esta vez s puedes copiar y pegar, aunque te conviene fijarte en el contenido que estas a
nadiendo.
En la clase Alumno a
nadiremos:
<set name="asignaturasMatriculado" table="Alumnos_Matriculados"
cascade="save-update" inverse="true" sort="unsorted"
mutable="true" optimistic-lock="true" embed-xml="true">
<key column="nif" on-delete="noaction" />
<many-to-many column="codasig" class="Clases.Asignatura"
embed-xml="true" not-found="exception" unique="false" />
</set>
y para Asignaturas a
nadiremos:
<set name="alumnosMatriculados" table="Alumnos_Matriculados"
sort="unsorted" inverse="false" mutable="true"
optimistic-lock="true" embed-xml="true">
<key column="codasig" on-delete="noaction" />
<many-to-many column="nif" class="Clases.Alumno"
embed-xml="true" not-found="exception" unique="false" />
</set>
Ademas hay que crear sus correspondientes funciones get y set (eso ya lo hemos hecho por ti, puedes
verlo en las clases).
Ahora ejecuta la clase ObjetosRelacionesMuchos.java4 y comprueba el resultado directamente en
MySQL. Ha sucedido lo que esperabas?
Ejercicio 8. Comenta como ha cambiado el esquema de tu base de dtos.
4 Recuerda

cambiar el nombre de la clase a ejecutar en el di


alogo de run.

6.4.

Cargando objetos de la base de datos

Hasta ahora hemos probado como podemos hacer que los datos de nuestro programa Java persistan
en una base de datos relacional. Ahora vamos a realizar la funcion inversa, vamos a cargar la informacion
de nuestra base de datos en nuestros objetos. Para comprobar que se hace correctamente imprimiremos los
resultados por la consola. La clase que vamos a ejecutar es CargarDatos.java.
Para obtener los datos de un objeto conociendo su clave primaria debemos hacerlo de la siguiente
manera:
Asignatura asig = (Asignatura) sesion.load(Clases.Asignatura.class, "IG18");
Para obtener todos las instancias de los objetos de una clase determinada haremos lo siguiente:
Query query = sesion.createQuery("From Alumno");
List alumnos = query.list();
Y, por u
ltimo, para obtener todos las instancias de los objetos de una clase determinada que cumplan
una determinada condicion, utilizamos un query de HBL (Hibernate query Languaje):
Query query1 = sesion.createQuery("From Profesor where nombre=" +"mon");
List profesores = query1.list();
for (int i=0; i<profesores.size();i++){
((Profesor)(profesores.get(i))).imprimir();
}
Ejercicio 9. Describe brevemente, pero de modo que se entienda, para que se esta utilizando Hibernate
en esta practica.

También podría gustarte