Está en la página 1de 57

Java Persistence API

 En las aplicaciones desarrolladas en lenguaje orientados a


objetos los datos manipulados dentro de la aplicación
generalmente son objetos creados a partir de una clase.
En dichos objetos se administra la información y lógica
que administra dicha información. Dicha información
dentro de la aplicación no es persistente y un modo muy
común para solucionar ese problema es usando bases de
datos. Como se sabe las bases de datos almacenan datos
discretos o atómicos y las relaciones entre las entidades se
da a través de relaciones, concepto que en POO no existe,
entonces surge la pregunta ¿Cómo persistir objetos en una
base de datos que no almacena objetos?.
 Los DAOs fueron una solución pero la cantidad de código
que se requiere para crearlos desestimula su uso.
 El mapeo es una técnica de
programación que permite una
transformación transparente
entre los datos de una aplicación
orientada a objetos y los datos
de una base de datos relacional.
 ORM significa Mapeo-Objeto-
Relación, nombre que da
entender que los objetos serán
transformados en registros de la
BD y viceversa. Esta técnica
posibilita el uso de las
características propias de la
orientación a objetos en el
manejo de la información.
 Utilizar un ORM tiene una serie de ventajas que nos facilitan
enormemente tareas comúnes y de mantenimiento:
 Reutilización: La principal ventaja que aporta un ORM es la reutilización
permitiendo llamar a los métodos de un objeto de datos desde distintas
partes de la aplicación e incluso desde diferentes aplicaciones.
 Encapsulación: La capa ORM encapsula la lógica de los datos pudiendo hacer
cambios que afectan a toda la aplicación únicamente modificando una
función.
 Portabilidad: Utilizar una capa de abstracción nos permite cambiar en mitad
de un proyecto de una base de datos MySQL a una Oracle sin ningún tipo de
complicación. Esto es debido a que no utilizamos una sintaxis MySQL, Oracle
o SQLite para acceder a nuestro modelo, sino una sintaxis propia del ORM
utilizado que es capaz de traducir a diferentes tipos de bases de datos.
 Seguridad: Los ORM suelen implementar mecanísmos de seguridad que
protegen nuestra aplicación de los ataques más comúnes como SQL
Injections.
 Mantenimiento del código: Gracias a la correcta ordenación de la capa de
datos, modificar y mantener nuestro código es una tarea sencilla.
 ORM para java se define a través de la API de
programación conocida como JPA. Esta API busca
unificar la manera en que funcionan las utilidades que
proveen un mapeo objeto-relacional para de esa
forma no perder las ventajas de la orientación a
objetos al interactuar con una base de datos. Entre las
implementaciones de esta API se encuentran:
 EclipseLink
 TopLink
 Hibernate
 OpenJPA
 El mapeo en JPA se hace a través de
anotaciones sobres las clases que indican
como se relacionan los atributos de estas con
los campos en la base de datos y como se
establecen las relaciones entre las clases y las
relaciones entre las tablas.
 El paquete java que implementa el API es
 Javax.persistence
 Supóngase la siguiente base de datos
 De esta base de datos se puede inferir:
 Un empleado tiene varios teléfono.
 Un empleado solo tiene un puesto

 El primer paso es crear las clases que


representaran las tablas
TABLA CLASE
 Para que un proyecto pueda usar ORM a
través de JPA se debe decidir que proveedor
de persistencia se usara. En nuestro caso se
usara EclipseLink para JPA 2.0
 Agregue a las librerías del proyecto el Driver
JDBC y las librerías eclipselink-2.0.0.jar y
eclipselink-javax.persistence-2.0.jar
 Una entidad es una clase que es persistente
usando Jpa. Para que una clase se considere
entidad debe cumplir los siguiente requisitos
minimos: Una anotacion
siempre empieza
 Implementar la anotación @Entity con @(arroba)
 Ser serializable
 Definir un constructor por defecto
 Definir un campo como llave primaria usando la
anotacion @Id
Indica que es una
entidad @Table(name=“nombre tabla en bd”) indica la
tabla en la BD que representa esta entidad.

@Id indica que el campo es la PK

@Column(name=“campo en la tabla que representa”)

El false indica que el campo es not null en la BD


 En JPA se pueden Mapear las siguientes
relaciones
 Uno a muchos: @OneToMany
 Uno a uno: @OneToOne
 Muchos a muchos: @ManyToMany
 Muchos a uno: @ManyToOne
 Entre teléfono y Empleado hay una relación de
uno a muchos en empleado(un empleado tiene
muchos telefonos) y de muchos a uno en
telefono (muchos telefonos a un solo empleado)
 En cada uno de las entidades involucradas en
la relación se crean atributos de de la entidad
relacionada.
 En empleado un Arreglo de telefonos
 En teléfono, un Empleado que es el dueño del
teléfono.
@OneToMany define que un
empleado tiene muchos teléfonos. El
parámetro de la anotación mappedBy
indica que esta relación esta conectada
con el atributo “empleado” de la
entidad Telefono. Se sabe que es la
entidad Telefono porque el arreglo es
de telefonos.
@ManyToOne indica que hay
una relación de Muchos a uno con
Empleado y @JoinColumn indica
que esa relación se da a través del
campo “empleado” de la tabla
teléfono en la BD

@JoinColumn se usa en la entidad que


posee la relación(tabla secundaria) y
mappedby en la entidad que apunta la
relación(tabla primaria)
 El Id de la tabla puesto es auto numérico. JPA provee la
posibilidad de gestionar estos campos también.

@GeneratedValue indica que el


valor del campo se genera
automáticamente. strategy define
como se genera ese valor y
GenerationType.IDENTITY define
que se genera auto numérico
 La empleo tiene como llave primaria una llave primaria, esto
obliga a que la entidad tenga la llave primaria(empleado-cedula) y
la relación con empleado (entidad empleado)
 La relación entre estas tablas es la siguiente:
 Empleado-empleo: una empleo tiene un solo
empleado y viceversa. Esto se da ya que la llave
primaria de empleo es a su vez foránea de
empleado. Esta es una relación de uno a uno.
 empleo-Puesto: un puesto puede estar en
muchos empleos debido a que varios trabajadores
pueden tener el mismo empleo y una empleo
tiene un puesto que indica el empleo del
empleado.
Empleado Empleo

Empleado posee un empleo que se


conecta al atributo empleado de la
El Empleo posee un empleado que hace
entidad Empleo
referencia al campo ” empleado” de la
tabla Empleo
Estos dos atributos
hacen referencia al
mismo campo de la
BD, uno como PK y
otro como relacion.

 Cuando una entidad tiene dos atributos que apuntan al


mismo campo de la BD, se debe decidir cual de los dos
va a dar el valor a dicho campo. La solución es indicar
cual no lo va a hacer a través de los parámetros
insertable y updatable de @Column o @JoinColumn.
Se establece que el valor del campo de la
El atributo PK(@Id) se deja intacto BD no será ni creado(insertable=false) ni
indicando que dicho atributo será modificado(updatable=false) con el valor
quien defina que valor tendrá el
que posea este atributo de la entidad.
campo en la BD
Puesto Empleo

U n puesto es compartido por muchos muchos empleos ocupan el mismo


empleados cargo.
 Las operaciones que se realizan sobre las entidades
son:
 Crear-persist
 Actualizar-merge
 Buscar-find
 Borrar-remove

 El objetivo del mapeo es poder implementar la


persistencia de objetos en bases de datos y las
operaciones anteriormente descritas son las
operaciones básicas que se realiza sobre cualquier
objeto.
 Antes de implementar completamente JPA
en nuestro proyecto se debe crear algo que se
denomina “Unidad de Persistencia”. La
unidad de persistencia es un archivo XML
donde se define una lista de entidades, el tipo
de transacciones que se tendrán, el
proveedor de persistencia(implementacion
de JPA) y la conexión a la base de datos.
Nombre de la unidad de
persistencia y tipo de
transacciones.

Proveedor de
persistencia
(eclipse link)
Lista de
entidades

Propiedades de
conexión con la
BF
 El EntityManager es un elemento que administra las
operaciones sobre las entidades. La clase
javax.persistence.EntityManager es la interfaz principal de
JPA utilizada para la persistencia de las aplicaciones. Cada
EntityManager puede realizar operaciones CRUD (Create,
Read, Update, Delete) sobre un conjunto de objetos
persistentes. El EntityManager se crea a a partir de los
datos definidos en la unidad de persistencia. En una
aplicación de escritorio el EntityManager se crea así:
Persistence.createEntityManagerFactory crea una factoría(fabrica de
objetos). Esta factoría recibe como parámetro el nombre de la unidad de
persistencia definido en el XML. El EntityManagerFactory es el encargado de
crear el EntityManager.

Nombre de la unidad de persistencia

La EntityManagerFActory crea el entityManager.


 Un contexto de persistencia administra un
conjunto de entidades que a su vez es manejado
por un EntityManager. El contexto de
persistencia lleva el registro del estado y/o los
cambios que puedan ocurrirle a una entidad. El
EntityManager por su parte hace uso de los
servicios que provee el contexto de persistencia
para enviar (commit) o deshacer estos cambios.
Tan pronto como se crea un objeto
EntityManager éste es asociado implícitamente
con el contexto de persistencia correspondiente.
 Buscar es la operación mas básica en la
persistencia. Para buscar se usa el método
find del EntityManager. El contrato de ese
método es el siguiente:
public Entity find(Entity.class,Object PK)

 Este método recibe como parámetro la clase


de la entidad que debe buscar y la llave
primaria de esa entidad y retorna la entidad
que posee dicha PK o null si no esta.
Tipo de entidad que
se busca
Valor de la PK de la
entidad

Este método busca el empleado en la BD. Como el empleado contiene los


teléfonos, lo ideal seria que al buscar el empleado, este venga con los teléfonos.
Pero se sabe que los telefonos estan en otra tabla y la relacion del empleado con
estos es de uno a muchos.
 La asociación o fetch entre
las entidades define como
se cargaran los elementos
asociados cuando se hace
una búsqueda sobre la
entidad. Por ejemplo el
empleado tiene los
teléfonos que están en una
colección. JPA puede traer
los teléfonos junto con el
empleado si se configura la
relación (oneToMany) para
tal fin
 La asociación(fetch) entre las entidades permite
definir cuando se debe cargar el campo en
cuestión. Fetch puede ser de dos tipos:
 EAGER: indica que el campo en cuestión se cargara en
el momento que se busque la entidad involucrada.
 LAZY: el campo se cargara por demanda, o lo que es
decir, cuando se requiera.
 EAGER propicia el uso de mas memoria del
sistema ya que debe guardar mas información
por entidad, pero en velocidad es mejor EAGER
porque los datos se tienen listos con la entidad
buscada.
 Para establecer un tipo de asociación en una
entidad se usa el parametro fetch de la
relación así:
Se indica que cuando se busque el
empleado, se busquen
inmediatamente sus
telefonos(fetch=FetchType.EAGER)
 Para almacenar una entidad se usa el método
persist del entityManager que recibe como
parametro la entidad a almacenar.

Se crea la entidad y se coloca en


el metodo persist.
 Cuando se almacena, se actualiza o se borra
información, esta operación debe estar
delimitada por una transacción.
 una transacción permite operaciones sobre
datos persistentes de manera que agrupados
formen una unidad de trabajo transaccional, en
el que todo el grupo sincroniza su estado de
persistencia en la base de datos o todos fallan en
el intento, en caso de fallo, la base de datos
quedará con su estado original. Maneja el
concepto de todos o ninguno para mantener la
integridad de los datos
 Para delimitar una transacciones primero se
inicia con el metodo begin y al final commit()

Se crea la
transaccion
Inicio transaccion

Operaciones de
persistencia

Fin transaccion
 Cuando se persiste, edita o elimina una entidad.
Las entidades poseen atributos que en muchas
ocasiones no nos tipos de datos primitivos, si no
otras entidades.
 Si se creara el empleado y se le asignara el
arreglo de teléfonos, este se debería almacenar
junto con el empleado sin mas esfuezo. Para que
ocurra este comportamiento se configuran las
relaciones en la entidad principal con el
parametro cascade.
 La propiedad cascade define con qué tipo de operaciones se
realizarán operaciones en "cascada", es decir se propagarán a las
entidades relacionadas, en nuestro caso a los proyectos. Esta
propiedad puede tener los siguientes valores:
 CascadeType.PERSIST - Cuando persistamos la entidad todas las
entidades que contenga esta variable serán persistidas también.
 CascadeType.REMOVE - Cuando borremos la entidad todas las
entidades que contenga esta variable se borrarán del mismo modo.
 CascadeType.REFRESH - Cuando actualicemos la entidad todas las
entidades que contenga esta variable se actualizarán.
 CascadeType.MERGE - Cuando hagamos un "merge" de la entidad
todas las entidades que contenga esta variable realizarán la misma
operación.
 CascadeType.ALL - Todas las operaciones citadas anteriormente.
Indica que los telefonos se
almacenaran junto con su
empleado cuando este se persista,
modifique o eliminen.
 Como se dijo en el persist, la actualización de un registro a
través del EntityManager se debe hacer dentro de una
transacción. Para actualizar un registro se usa el método
merge que recibe como parametro la entidad.
Se busca y cambia el
nombre

Se crea la transaccion

Se actualiza

Se actualizase cierra
la transaccion
Para borrar se usa el método remove. El uso de este método debe estar
enmarcado dentro de una transacción. El método recibe la entidad a eliminar.
Se busca y cambia el
nombre

Se crea la transaccion

Se actualiza

Se actualizase cierra
la transaccion
 Las operaciones básicas sobre las entidades
no son suficientes para implementar todas las
funcionalidades de una aplicación. El find del
entitymanager solo entrega la entidad que
tenga la PK solicitada. Pero si se necesitara
todos los empleados, o todos los empleados
gerentes, o todos los cargos cuyo sueldo esta
entre 1’000.000 y 2’ooo.ooo,el método find
no sirve para esto.
 Para realizar consultas sobre las entidades en
JPA se usa un lenguaje muy similar al SQL
llamado JPQL (Java Persistence Java
Language). Este lenguaje es independiente
del modo en como se implemente la
persistencia, ya sea en BD, archivos,
repositorios de objetos, etc.
 JPQL tiene sentencias de tipo select, update
y delete donde las consultas que usan estas
sentencias se ejecutan sobre los objetos
administrados por el EntityManager.
 Una consulta select es un String que contiene las
siguientes partes:
 select : donde se determinan los objetos o valores a ser
seleccionados.
 from: aquí se provee las declaraciones de los objetos a
consultar, las expresiones definidas en las otras clausulas
de la consulta operaran sobre estos objetos.
 where: restringe los resultados entregados por la consulta.
 En general, la estructura de una consulta es la
siguiente:
select [valores a consultar del objeto obj] from Entity obj where [condiciones]
 Seleccionar todos los empleados:
Select emp from Empleado emp

Aquí indicamos que la consulta


se hace sobre la entidad
empleado. En el from se
El select determina que declara un objeto de este tipo
valores se tomaran de la el cual se usa en las otras
consulta. aqui se indica que se partes de la consulta.
esta consultando todo el
empleado declarado en el
from.
 Seleccionar los puestos cuyo sueldo sea
mayor a 1’000.000

select p from Puesto p where p.sueldo>1000000

la consulta se hara sobre la P es el objeto declarado en


Se retornaran entidad Puesto. Para poder el from que es de tipo
todos los usar los atributos de esta, se Puesto. El puesto en sus
atributos de declara el puesto p atributos tiene el sueldo, el
puesto. cual se compara con
1’000.000
 Los empleados que sean gerentes
(puesto.ID=1)
 En SQL tradicional, se necesitaría hacer un
JOIN entre la tabla empleado, puesto y
empleo.
 Desde las entidades, para conocer el puesto
de un empleado se accede a su empleo, de alli
al puesto de ese empleado.
select emp from Empleado emp where emp.nomina.puesto.id=1

emp.nomina.puesto.id=1
Empleado de Atributo Puesto que esta
la consulta nomina del en El Id del puesto
empleado nomina(empleo)
 La consultas en JPQL se crean a través de la
Clase Query. Para crear una consulta se usa el
método createQuery del EntityManager.
 Query q=em.createQuery(Stringconsulta)
 Para obtener el resultado de la consulta usa el
método de Query getResultList() para obtener
una lista de resultados o getSingleResult() para
obtener un solo resultado.
 getResultList() retorna un List de entidades.
 Query q=em.createQuery(“select emp from Empleado emp”);
List<Empleado> trabajadores=q.getResultList();

1. Se crea el Query a través del método createQuery


del EntityManager. Este método recibe como
parámetro un String con la Consulta JPQL.
2. Se ejecuta la consulta con getResulList. Este
retorna un List de empleados ya que la JPQL se
hace sobre la entidad Empleado.
 Como es sabido, una consulta puede
generarse dinámicamente en tiempo de
ejecución con datos suministrados por el
usuario. Los parámetros en la consulta se
reconocen por que son identificador valido
precedido de dos puntos(:)
 select p from Puesto p where p.sueldo>:minSueldo

 Aquí minSueldo es un parámetro por que antes tiene (:) dos


puntos.
 Para establecer el valor de los parámetros se
usa el método del Query
setParameter(<nombreParametro>,<valorParametro>)
 por ejemplo, para la consulta anterior con el parámetro
minSueldo se establecería así:
 q.setParameter(“minSueldo”,1000000). A
continuación, un ejemplo completo.
Query q;
q=em.createQuery("select emp from Empleado emp where “+
“ emp.nomina.puesto.id=:idpuesto");
q.setParameter( “idPuesto” ,21);
idPuesto es el nombre
El valor del parametro del parámetro- véanse
idPuesto en la consulta los dos puntos(:) que lo
sera 21. anteceden

List<Puesto> puestos=q.getResultList();

También podría gustarte