2. 1. Frameworks de Persistencia
• Un framework de persistencia es una API que permite almacenar
datos
o Los soporte de almacenamiento son variados, desde ficheros a
bases de datos
• En Java se han utilizado diversos frameworks de persistencia:
o JDBC
o Enterprise Java Beans: el estándar EJB 2.0 define un tipo de
bean llamado Entity Bean, el cual puede ser persistido por el
servidor de aplicaciones. Se definió EJBQ QL como lenguaje
neutro de acceso a datos. Muy complejo de configurar
o Java Data Objects: mucho más simple a EJB 2.0 y surge como
alternativa a éste, aunque nunca llegó a formar parte del
éstandar.
3. 1. Frameworks de Persistencia
• Los desarrolladores buscaron fuera del estándar frameworks de
persistencia fáciles de utilizar y fuertemente implantados en el
mercado:
o Toplink: con licencia comercial
o Hibernate: OpenSource y con ampliamente difundido
• El grupo de trabajo dentro de EJB 2.0 decidió estandarizar estas
APIs, dando como resultado la definción 3.0 de EJB, el cual incluye
una serie de interfaces que definen el estándar de Persistencia en
Java: Java Persistence API o JPA
• La gran mayoría de los frameworks existentes hasta el momento
ofrecen una implementación de dicho estándar
4. 1. Object-Relational Mapping
• ¿Qué es un ORM?
o El modelo del dominio está formado por clases
o El modelo de BBDD está formado por tablas
o Ambos conceptoss se parecen y están estrechamente
relacionados, pero no son lo mismo
• Un ORM, o Object-Relational Mapping define la relación entre
clases de un modelo y tablas de una BBDD, haciendo que las
instancias de dichas clases puedan ser almacenadas en tablas de
la BBDD de forma automática y que, a su vez, el contenido de las
tablas pueda ser manejado como objetos.
5. 1. Object-Relational Mapping
• Un ORM ideal:
o Debe manejar objetos, no tablas
o Requiere que el mapeo se realice por alguien con conocimientos
de la tecnología ORM, no vale alguien qué no conozca
mínimamente su funcionamiento
o Debe ser todo lo transparente que se pueda, aunque debe
permitir el control de los objetos y su ciclo de vida
o Debe ser simple y eficiente, ya que si no puede causar más
problemas que soluciones aporte
6. 1. Java Persistence API
• JPA es un framework de persistencia Java, ligero y basado en
POJOs o beans.
• Permite definir el mapeo objeto-relacional aunque también ofrece
soluciones arquitecturales para integrar la persistencia en
aplicaciones que requieran alta escalabilidad
• Define un lenguaje que permite lanzar consultas sobre las
entidades y sus relaciones, basado en EJB QL, llamado Java
Persistence Query Language o JPQL
• La configuración se realiza con un pequeño fichero XML y las
relaciones o metadatos de las entidades se definen mediante
anotaciones en las propios beans (aunque también se pueden
definir en el fichero XML anterior)
7. 2. Entidades
• Una entidad es algo que tiene atributos y relaciones y todos ellos
deben ser persistidos
o En esencia es un nombre o un grupo de estados asociado es
una única unidad
• En el paradigma de Orientación a Objetos, una entidad se modela
como un objeto que puede mantener relaciones con otros objetos
8. 2. Entidades
• ¿Qué es lo que convierte un objeto en una entidad?
o Persistibilidad: deben poder ser almacenados en un almacén
de datos y recuperados posteriormente
o Identidad: debe poder ser identificado de forma única
o Transaccionalidad: solo es posible crear entidades,
actualizarlas o borrarlas en el contexto de una transacción.
o Granularidad: las entidades son un agregado de tipos básicos o
de grano fino y pueden mantener relaciones con otras entidades
9. 2. Entidades
• Metadatos de la entidad
o Mediante anotaciones en las clases
o Definidos en un fichero XML
• JPA provee una configuración por defecto para las entidades,
siendo solo necesario especificar aquellos metadatos que sean una
excepción al valor por defecto
10. EJERCICIO
• Crea un bean Persona, con los atributos:
o nombre
o apellidos
o edad
• Utiliza la anotación @Entity sobre la clase para definirlo como
entidad
• Define un atributo del bean como el atributo identificativo de la
entidad anotándolo con @Id
11. 2. Entidades
• El Gestor de Entidades o Entity Manager es el componente de JPA que
encapsula prácticamente toda la funcionalidad del API:
o Permite persistir y recuperar entidades
o El conjunto de instancias de entidades gestionadas por el Entity Manager
se llama contexto de persistencia
o No es posible que dentro de un contexto de persistencia existan dos
entidades del mismo tipo con la misma identidad
o Un gestor de persistencia gestiona un número limitado de tipos de
entidades, aunque pueden utilizarse distintos gestores que gestionen
contextos disjuntos
o Los gestores de persistencia están implementados por distintos
proveedores de persistencia
12. EJERCICIO
• Obtén un EntityManager con el siguiente código:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("curso_jpa");
EntityManager em = emf.createEntityManager();
• Utilizando el EntityManager, persiste el bean creado
anteriormente utilizando el siguiente código:
em.getTransaction().begin();
em.persist(persona);
em.getTransaction().commit();
13. EJERCICIO
• Cierra el EntityManager y el EntityManagerFactory antes de
finalizar la ejecución del código:
em.close();
emf.close();
• Ejecuta el código creado sobre una BBDD vacía y comprueba
el resultado en la BBDD
14. 3. Anotaciones básicas en JPA
• Definir una clase como entidad: @Entity
• Marcar un atributo como identificativo: @Id
• Mapear una tabla: @Table(name="nombre", schema="esquema")
• Mapear atributos: @Column(name="nombre")
• Marcar un atributo como objeto grande: @Lob
• Carga perezosa de un atributo: @Basic(fetch=FetchType.LAZY)
o FetchType.LAZY
o FetchType.EAGER
15. 3. Anotaciones básicas en JPA
• Tipos enumerados: @Enumerated(EnumType.STRING)
o EnumType.STRING
o EnumType.ORDINAL
• Datos temporales: @Temporal(TemporalType.DATE)
o TemporalType.DATE
o TemporalType.TIME
o TemporalType.DATESTAMP
• Para que un atributo sea ignorado por JPA debemos utilizar el
modificador transient o la anotación @Transient
16. 3. Anotaciones básicas en JPA
• Generación de identificadores automática: podemos utilizar la anotación
@GeneratedValue sobre el identificador de una entidad para que se le asigne
un identificador de forma automática cuando sea persistida
• Existen varias estrategias para asignar estos identificadores:
o Automática (strategy=GenerationType.AUTO): utiliza una de las
siguientes estrategias, en función de la implementación
o Mediante tabla (strategy=GenerationType.TABLE): utiliza una tabla
para almacenar distintos identificadores asignados de forma automática
o Mediante secuencia (strategy=GenerationType.SEQUENCE): utiliza una
secuencia de la BBDD para asignar los identificadores
o Identidad (strategy=GenerationType.IDENTITY): utiliza el sistema
autonumérico de la BBDD si ésta lo soporta
17. EJERCICIO
• Modifica la entidad Persona:
o El identificador debe ser generado automáticamente.
Prueba distintos métodos y comprueba el resultado en
BBDD
o Mapea contra una tabla distinta y cambia el nombre a
alguno de los atributos en la BBDD
o Utiliza un atributo de tipo enumerado para indicar la
situación laboral (Cuenta_Ajena, Cuenta_Propia,
Estudiante, Paro). Utiliza los dos tipos de mapeos para tipos
enumerados y comprueba la BBDD.
18. 4. Relaciones entre entidades
Relaciones Muchos a Uno
@Entity
public class Empleado {
...
@ManyToOne
private Departamento departamento;
...
}
• Si queremos modificar el nombre de la columna que se utilizará para hacer
join, debemos añadir la anotación @JoinColumn(name="columna)
19. 4. Relaciones entre entidades
Relaciones Uno a Uno (bidireccionales)
@Entity
public class Empleado {
...
@OneToOne
@JoinColumn(name="parking_id")
private Parking parking;
...
}
@Entity
public class Parking {
...
@OneToOne(mappedBy="parking")
private Empleado empleado;
...
}
20. 4. Relaciones entre entidades
Relaciones Uno a Muchos
• Partimos del ejemplo Empleado de Muchos a Uno. En este caso la entidad propietaria
siempre es la de la parte del "Muchos" y en dicha entidad debe utilizarse una
anotacion @ManyToOne:
@Entity
public class Departamento {
...
@OneToMany(mappedBy="departamento")
private Collection<Empleado> empleados;
...
// sin usar genéricos
//@OneToMany(mappedBy="departamento", targetEntity=Empleado.class)
//private Collection empleados;
...
}
@Entity
public class Empleado {
...
@ManyToOne
private Collection<Empleado> empleados;
...
}
21. 4. Relaciones entre entidades
Relaciones Uno a Muchos
• También es posible usar otro tipo de colecciones para establecer
asociaciones entre entidades
@Entity
public class Departamento {
...
@OneToMany(mappedBy="departamento")
@MapKey(name="nombre")
private Map<String, Empleado> empleados;
...
}
22. 4. Relaciones entre entidades
Relaciones Muchos a Muchos
@Entity
public class Empleado {
...
@ManyToMany
private Collection<Proyecto> proyectos;
...
}
@Entity
public class Proyecto {
...
@ManyToMany(mappedBy="proyectos")
private Collection<Empleado> empleados;
...
}
23. 4. Relaciones entre entidades
Relaciones Muchos a Muchos
• Modificación del nombre y columnas de la tabla de asociación
@Entity
public class Empleado {
...
@ManyToMany
@JoinTable(name="EMP_PROY",
joinColumns=@JoinColumn(name="EMP_ID"),
inverseJoinColumn=@JoinColumn(name="PROY_ID"))
private Collection<Proyecto> proyectos;
...
}
24. 5. Operaciones con entidades
• Persistencia:
o em.persist(entidad);
• Recuperación por ID:
o Entidad entidad = em.find(Entidad.class, id);
• Eliminación:
o em.remove(entidad);
• Querys
Query query =
em.createQuery("SELECT e FROM Entidad e WHERE e.id > 100");
Collection entidades = query.getResultList();