You are on page 1of 74

API Java de persistencia

Aplicaciones web
y Bases de datos
Normalmente las aplicaciones web guardan datos
de distintos tipos, tanto datos producidos durante
la interaccin de los usuarios con la aplicacin
como datos que son mostrados a los usuarios.
Java incluye mecanismos para permitir que los
programas accedan a bases de datos.
Java EE tambin incluye mecanismos especficos
para hacer ms eficiente el acceso a bases de
datos.

Servidor de bases de datos


MySQL Server 5.5
Usuario: root, Clave: mysql
Arranque: automtico (servicio MySQL)
Parada:
C:\Archivos de programa\MySQL\MySQL Server 5.5\bin\

mysqladmin -uroot -pmysql shutdown


Administracin:
C:\Archivos de programa\MySQL\MySQL Server 5.5\bin\

mysqladmin -uroot -pmysql

Servidor de bases de datos, II


Acceso desde cliente:
C:\Archivos de programa\MySQL\MySQL Server 5.5\bin\

mysql -uroot -pmysql


Finalizacin: quit;

Bases de datos:
CREATE DATABASE CLS;
SHOW DATABASES;
USE CLS;

Tablas:
SHOW TABLES;

Servidor de bases de datos, III


Catlogo:
information_schema (base de datos)
TABLES(TABLE_SCHEMA, TABLE_NAME,
)
COLUMNS(TABLE_SCHEMA,
TABLE_NAME, COLUMN_NAME, )

JDBC
JDBC es una biblioteca de Java que
permite la conexin a bases de datos
relacionales.
JDBC se utiliza mediante un driver que al
cargarse permite que un programa Java
se conecte a un servidor de bases de
datos como un usuario determinado
JDBC proporciona clases para
representar las conexiones, consultas
SQL y resultados de las mismas.

JDBC, II
Un programa Java que utiliza JDBC hace lo
siguiente:
Carga el driver JDBC (la clase que gestiona el
acceso a bases de datos).
Crea una conexin a la base de datos.
Crea una consulta en base a cdigo SQL.
Ejecuta la consulta, obteniendo un conjunto de
resultados (o void).
Itera si es necesario sobre los resultados.
Cierra la conexin.

Utilizacin de JDBC mediante la


API de persistencia
La API de persistencia, que es parte de JEE pero
se puede utilizar en otras aplicaciones Java, permite
la especificacin de manera sencilla de aplicaciones
con un nmero elevado de usuarios simultneos
que acceden de manera eficiente a bases de datos.
Cuando una aplicacin Java utiliza la API de
persistencia (JPA), se crea un pool de conexiones
JDBC que se reutilizan por los distintos hilos de la
aplicacin.

JPA: Consultas
El Lenguaje de Consultas de Persistencia
de Java (JPQL) permite especificar
consultas a bases de datos relacionales
en forma parecida a SQL desde un
programa Java.

JPA: Consultas, II
Los objetos que implementan la interfaz
TypedQuery<?> de JPA representan
consultas del tipo anterior.
Los objetos de la clase anterior que
representan consultas que devuelven
valores (tipo SELECT) al ejecutar la
consultas devuelven listas de objetos.

Recordatorio:
Consultas en SQL
INSERT INTO PERSONA
VALUES (Pepe, Prez, inglesa)
SELECT * FROM PERSONA
UPDATE PERSONA
SET NACIONALIDAD=espaola
DELETE FROM PERSONA

Consultas en JPQL
SELECT p FROM Persona p
Persona es una entidad (clase)
p representa una variable Java de la clase
El resultado de la ejecucin de la consulta es
una lista de objetos de la clase

Se pueden aadir otras clusulas:


SELECT p FROM Persona p
WHERE p.nombre = Pepe

Consultas en JPQL, II
Cuestiones pendientes de estudiar:
Programacin de consultas
Acceso a resultados devueltos por las
consultas
Definicin de entidades
Sincronizacin

JPA: EntityManager
Para crear y ejecutar consultas mediante JPA es
necesario crear antes un objeto que implementa
la interfaz EntityManager, que se ocupa de la
gestin de los datos y de objetos que los
representan.
A continuacin veremos cmo se utilizan y cmo
se crean los EntityManagers.
Tras esto veremos cmo se definen las clases de
objetos que representan registros de una base de
datos.

JPA: Programacin de
consultas
Para crear una consulta se utiliza el mtodo
createQuery de la clase EntityManager, cuyo
argumento es la cadena de caracteres que
define la consulta JPQL:
TypedQuery<Persona> query =
em.createQuery(
SELECT p FROM Persona p,
Persona.class);

JPA: Acceso a resultados


Para ejecutar una consulta de tipo SELECT
se utiliza el mtodo getResultList, que
devuelve una lista de objetos:
java.util.List<Persona> pers =
query.getResultList();

Gestin de persistencia
en Java EE
En Java EE, cuando un contenedor activa un objeto,
puede inyectar una EntityManagerFactory que sea
un atributo suyo o directamente un EntityManager.
La inyeccin directa de EntityManager solamente se
puede hacer en un contexto monohilo (EJB sin
estado, beans gestionados de JSF, ).
La inyeccin de EntityManagerFactory se puede
hacer en cualquier contexto (servlet,
ServletContextListener, pgina JSP, bean gestionado
de JSF o EJB).

Gestin de persistencia
en Java EE: Ejemplos
Ejemplo de inyeccin de E.M.Factory:
@PersistenceUnit
private EntityManagerFactory emf;
EntityManager em =
emf.createEntityManager();
Ejemplo de inyeccin de EntityManager:
@PersistenceContext
EntityManager em;

Recursos en Java EE
Los servidores de aplicaciones web permiten el
acceso a recursos externos como sistemas de
gestin de bases de datos o de colas de
mensajes.
El servidor registra los recursos, asocindoles
un nombre accesible a travs del protocolo
Java JNDI. El uso de JNDI es transparente.
La gestin de recursos se puede hacer desde
NetBeans o desde la aplicacin de
administracin del servidor de aplicaciones.

Consideraciones para la utilizacin


de la API de persistencia en el lab
Para acceder a una base de datos
mediante JPA hay que utilizar dos
recursos: un recurso JDBC y un pool de
conexiones JDBC.

Consideraciones para la utilizacin


de la API de persistencia en el lab, II
Un pool de conexiones JDBC es un
conjunto de conexiones JDBC a una base
de datos disponibles para ser reutilizadas
concurrentemente por distintos hilos de la
aplicacin.
Para especificar un pool de conexiones se
indica la base de datos, usuario,
contrasea, propiedades, etc.

Consideraciones para la utilizacin


de la API de persistencia en el lab, III
Un recurso JDBC es un proxy a un pool
de conexiones.
Para especificar un recurso JDBC hay que
indicar el nombre con que est registrado
el pool correspondientes y las
propiedades.

Consideraciones para la utilizacin


de la API de persistencia en el lab, III
Para crear un recurso JDBC y un
connection pool en el servidor de
aplicaciones hay dos posibilidades:
Localhost:4848 -> Resources -> JDBC
NetBeans -> Proyecto -> New persistence unit
-> new Data Source -> new Data Base
connection

Acceso a recursos JDBC desde


aplicaciones web
El fichero de configuracin persistence.xml
permite especificar las bases de datos
accesibles a una aplicacin y las entidades
que utiliza.
El fichero de configuracin debe incluirse en
el directorio /META-INF del mdulo
correspondiente.
La clusula persistence-unit permite
especificar un data-source.

Ejemplo de fichero persistence.xml


<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/...
xsi:schemaLocation="http://...">
<persistence-unit name="book" transaction-type="JTA">
<jta-data-source>jdbc/__default</jta-data-source>
<class>com.widgets.Order</class>
<class>com.widgets.Cust</class>
</persistence-unit>
</persistence>

Clases entidad
Son clases asociadas a tablas (una o varias)
en una base de datos.
Sus objetos se asocian a registros.
Se declaran mediante la anotacin @Entity.
La clave primaria se indica mediante la
anotacin @Id (obligatorio).
@Entity
public class Person { @Id int id; }

Clases entidad, II
Si la tabla primaria tiene un nombre
diferente de la clase, ste se especifica
mediante la anotacin @Table(name).
NetBeans permite la opcin de crear la
tabla (si no existe) al compilar el cdigo de
la clase

Clases entidad, III


Tipos de atributos:
Persistentes (ver prxima transparencia)
No persistentes (@Transient)
Embebidos (@Embedded), de otra entidad,
incluidos en la tabla de la primera
Generados automticamente
(@GeneratedValue)
Relaciones (prxima transparencia)

Clases entidad:
Atributos persistentes
Son todos salvo los no persistentes
Tienen que ser protegidos o privados
Tipos: Primitivos, wrappers, String,
temporales (Date, ), arrays de bytes y
chars, enumeraciones, clases embedibles
Colecciones: Collection, Set, List, Map

Definicin de entidades en
persistence.xml (alternativa)
<persistence>
<persistence-unit name=>
<jta-data-source></jta-data-source>

<class>com.widgets.Order</class>
<class>com.widgets.Cust</class>
</persistence-unit>
</persistence>

JPA bsico: Resumen


Las clases de entidades representan
registros de tablas. Se definen mediante la
anotacin @Entity.
Los recursos JDBC y los pools de
conexiones se utilizan por el servidor web
para implementar la conexin a la base de
datos. Se definen en el servidor.

JPA bsico: Resumen, II


Los recursos utilizados por una aplicacin
se especifican en el fichero
persistence.xml.
Los EntityManagers gestionan el acceso a
las bases de datos. Se inyectan en un
objeto gestionado por un contenedor o se
crean a partir de una fbrica inyectada.
Estn asociados a un recurso JDBC.

JPA bsico: Resumen, III


Los TypedQuerys pueden ejecutar
consultas JPA. Se crean a partir de ellas y
en su caso devuelven listas de entidades.

Ejercicio
[DBPERS0] Desarrollar una aplicacin
web que permita ver la lista de personas
incluidas en una base de datos de
personas sencilla, como la mencionada
en los ejemplos anteriores.

JPA: Programacin de
consultas, II
Se pueden definir TypedQuerys con tipo
atmico (Integer, String, etc.) para consultas
que seleccionan una sola columna:
TypedQuery<String> query =
em.createQuery(
SELECT p.nombre
FROM Persona p,
String.class);

JPA: Programacin de
consultas, III
Las consultas de actualizacin o borrado
se definen de forma similar:

UPDATE Persona p
SET p.nacionalidad=espaola
DELETE FROM Persona p
WHERE p.estado=fallecido

JPA: Programacin de
consultas, IV
Para ejecutar una consulta de tipo
UPDATE o DELETE se utiliza el mtodo
executeUpdate():
query.executeUpdate();

JPA: Programacin de
consultas, V
Se pueden definir consultas parametrizadas
utilizando patrones de parmetros:
TypedQuery<Persona> query=
em.createQuery(
SELECT p FROM Persona p
WHERE p.edad=?1);
pers = query.setParameter(1, 3).getResultList();

Ejercicio
[DBPERS1] Desarrollar una aplicacin
web que permita gestionar a travs de
Internet una base de datos de personas
sencilla, como la mencionada en los
ejemplos anteriores, permitiendo dar de
alta y de baja a personas y modificar sus
datos.

Ejercicios voluntarios
[DBFILE] Completar los ejercicios de los
temas anteriores que utilizan ficheros
(PyCE1, FAV, PyCE2, SWJSF, SWCC,
AJAXPERS) para guardar sus datos
sustituyendo los ficheros por una base de
datos.

JPA: Programacin de
consultas, VI
Se pueden utilizar consultas SQL
(consultas nativas) mediante el mtodo
createNativeQuery de la clase
EntityManager.
El objeto creado por
EntityManager.createNativeQuery
implementa la interfaz Query,
superinterfaz de TypedQuery<?>.

JPA: Programacin de
consultas, VII
Los registros obtenidos mediante el mtodo
Query.getResultList a partir de una consulta
SQL son arrays de objetos.
Ejemplo:
Object[] persona =
(Object[]) em.createNativeQuery(
"SELECT * FROM PERSONA)
.getResultList().get(0);
out.println(persona[0] + " " + persona[1]);

JPA: Programacin de
consultas, VIII
Se puede determinar el nmero del registro
a partir del cual se extraen los resultados y
el nmero mximo de resultados a extraer
en una consulta:
em.createQuery(
SELECT p FROM Persona p)
.setFirstResult(5).setMaxResults(9);

Bsqueda de objetos
individuales
Se hace mediante el mtodo find(Class<?
>, Object) de la clase EntityManager.
Utiliza su segundo argumento como clave
primaria.
Ejemplo:
Person p = e.find(Person.class, 2130);

Entidades persistentes:
Ciclo de vida
Las entidades persistentes pueden estar
desacopladas de la base de datos o
acopladas a ella a travs de un
EntityManager. En este caso estn en el
estado Managed (gestionadas).
Por ejemplo, una entidad persistente
creada a travs de una consulta a la base
de datos normalmente est gestionada por
el EntityManager que hace la consulta.

Entidades persistentes:
Ciclo de vida, II

SELECT

Detached

Managed
(em)

Entidades persistentes:
Ciclo de vida, III
Una entidad persistente creada mediante
new est desacoplada de la base de
datos y se encuentra inicialmente en el
estado New.
Si una entidad est en el estado New, en
la base de datos puede haber un registro
cuya clave primaria sea la misma de la
entidad.

Entidades persistentes:
Ciclo de vida, IV

New
new

Detached

SELECT

Managed
(em)

Entidades persistentes:
Ciclo de vida, V
Las entidades persistentes que estn en el
estado New pueden acoplarse a la base de
datos mediante el mtodo persist(Object)
de la clase EntityManager, que las gestiona
a partir de ese momento tras insertar los
registros necesarios en la base de datos.
Si en la base de datos ya hay un registro
con la misma clave primaria, se lanza una
excepcin.

Entidades persistentes:
Ciclo de vida, VI

New

[Aade registro]
em.persist(o)

new

SELECT

Detached

Managed
(em)

Entidades persistentes:
Ciclo de vida, VII
Las entidades persistentes gestionadas se
pueden desacoplar de la base de datos
mediante el mtodo close(Object) del
EntityManager que las gestiona, pasando a
estar en el estado Detached.
El mtodo merge(Object) de la clase
EntityManager permite volver a gestionar una
entidad persistente que est en el estado
Detached. Tras su ejecucin se actualizar la
base de datos con su contenido.

Entidades persistentes:
Ciclo de vida, VIII

New

[Aade registro]
em.persist(o)

new

SELECT
em.merge(o)
[objBD]

Detached

em.close(o)

Managed
(em)

Entidades persistentes:
Ciclo de vida, IX
Tanto en el estado New como en Detached
los cambios que origina el cambio de estado
de una entidad persistente no se trasladan
necesariamente a la base de datos de
inmediato (se hace cuando termina la
transaccin que se est ejecutando).
Lo mismo ocurre con los cambios en los
valores de los atributos persistentes de las
entidades gestionadas.

Entidades persistentes:
Ciclo de vida, X
Se puede forzar la realizacin inmediata en
la base de datos de los cambios pendientes
de realizar correspondientes a todas las
entidades gestionadas por un EntityManager
mediante el mtodo flush() del mismo.
Esto permite que cualquier otra consulta que
se haga refleje los cambios realizados en las
entidades gestionadas por el EM.

Entidades persistentes:
Ciclo de vida, XI

New

[Aade registro]
em.persist(o)

[objsBD]
em.flush()

new

SELECT

Managed
(em)

em.merge(o)
[objBD]
Detached

em.close(o)

Entidades persistentes:
Ciclo de vida, XII
Las consultas tienen asociado un modo de
flush, que permite hacer que siempre que se
ejecuten haya garantas de que la base de
datos est actualizada con respecto a
cambios en las entidades gestionadas.
El modo de flush puede ser AUTO o
COMMIT.
Los EntityManagers tambin tienen un
modo de flush.

Entidades persistentes:
Ciclo de vida, XIII
La actualizacin de los registros
correspondientes a las entidades
gestionadas por un EntityManager se
puede hacer mediante una llamada
explcita al mtodo flush() en el programa
o lo puede hacer el EntityManager al
ejecutar acciones previstas en su
funcionamiento (por ejemplo, cuando se
termina una transaccin).

Entidades persistentes:
Ciclo de vida, XIV
Tambin se puede actualizar una entidad
acoplada a una base de datos con los
valores que sta contiene. Esto se hace
mediante el mtodo
EntityManager.refresh(Object).
Se puede borrar de una base de datos la
informacin correspondiente a una entidad
acoplada a ella, mediante el mtodo remove
de la clase EntityManager. La entidad pasa
entonces al estado Removed.

Entidades persistentes:
Ciclo de vida, XV

New

[Aade registro]
em.persist(o)

new

SELECT
em.merge(o)
[objBD]

Detached

em.close(o)

[BD obj]
em.refresh(o)
[objsBD]
em.flush()
Managed
(em)
em.remove(o)
[Elimina registro]
Removed

Gestin de entidades:
Otros aspectos
em.setFlushMode(FlushModeType)
// AUTO (tras ejecucin de update)
// COMMIT (tras finalizar transaccin)
em.lock(Object, LockModeType)
// READ, WRITE
em.clear();
// Desconecta entidades, sin sincronizarlas
em.close();
// Cierra conexiones

Relaciones muchos a uno


Ejemplo
Tablas:
Persona(id int primary key, nombre varchar,
trabajo int ref Empresa.id)
Empresa(id int primary key, nombre varchar)

Entidades:
Persona(@Id int id; String nombre;
@ManyToOne Empresa trabajo) // Propietario
Empresa(@Id int id; String nombre)

Relaciones muchos a muchos


Ejemplo
Tablas:
Persona(id int primary key, nombre varchar,
trabajo int ref Empresa.id)
Empresa(id int primary key, nombre varchar)
Clientes(idE int ref Empresa.id,
idP int ref Persona.id
primary key (idE, idP))

Relaciones muchos a muchos


Ejemplo, II
Entidades:
Persona(@Id int id; String nombre;
@ManyToOne Empresa trabajo)
Empresa(@Id int id; String nombre;
@ManyToMany Set<Persona> clientes) // Prop

Se podra haber hecho propietaria a la


entidad Persona. La eleccin se debe basar
en criterios de eficiencia.

Relacin uno a muchos


Relacin inversa de otra muchos a uno
Se implementa por motivos de eficiencia (si
se va a utilizar con frecuencia)
Ejemplo:
Empresa(@Id int id; String nombre;
@ManyToMany Set<Persona> clientes;
@OneToMany(mappedBy=trabajo)
Set<Persona> trabajadores)

Relaciones muchos a muchos:


Relacin inversa
Se implementa por motivos de eficiencia (si
se va a utilizar con frecuencia)
Ejemplo:
Persona(@Id int id, String nombre;
@ManyToOne Empresa trabajo;
@ManyToMany(mappedBy=clientes)
Set<Empresa> contratistas)

Relaciones uno a uno


Ejemplo:
Empresa(; @OneToOne Persona director)
En la base de datos una relacin uno a uno no
se distingue de una muchos a uno, salvo quizs
por una restriccin de integridad
Las relaciones uno a uno se especifican
mediante la anotacin @OneToOne
La relacin inversa de una relacin uno a uno es
tambin una relacin uno a uno

Consultas y relaciones
Ejemplos: Empleados de Renfe
select p from Empresa e JOIN e.clientes p
where e.name=Renfe
(lista de Person)
Para poder hacer una consulta que atraviesa
una relacin, la relacin tiene que estar definida (en la clase de entidades persistentes)
en la direccin en la que es atravesada.

Entidades:
Jerarqua de herencia
La API de persistencia incluye varios
mecanismos para aprovechar la herencia
que proporciona Java

Relaciones y gestin de
entidades
La API de persistencia permite especificar que las
acciones de insercin y/o borrado de objetos
deben propagarse a travs de determinadas
relaciones.
Para ello se utiliza el atributo cascade de la
anotacin de la relacin, cuyos valores pueden
ser PERSIST, REMOVE o ALL.
Por ejemplo, si se quieren eliminar los objetos
relacionados con uno cuando se elimine, se utiliza
el atributo cascade=REMOVE de la relacin

Relaciones y gestin de
entidades, II
Ejemplo, continuacin:
Empresa(@Id int id, String nombre,
@ManyToMany Set<Persona> clientes,
@OneToMany(mappedBy=trabajo
cascade=REMOVE)
Set<Persona> trabajadores)

Transacciones en SQL
Una transaccin es una secuencia de
instrucciones SQL que se ejecutan
provisionalmente, pudiendo anularse en
cualquier momento o consolidarse al final.
Por ejemplo, un movimiento en una
cuenta corriente puede realizarse
mediante una transaccin que comprueba
que el usuario ha actuado correctamente
en el cajero automtico.

Transacciones en SQL, II
En una sesin de ejecucin de instrucciones
en un Sistema de Gestin de Bases de
Datos cualquier instruccin normal comienza
una transaccin si no hay una comenzada.
La instruccin COMMIT termina una
transaccin dando por buenos los cambios.
La instruccin ROLLBACK termina una
transaccin deshaciendo los cambios.

Transacciones en Java EE
Java EE permite definir transacciones que
abarcan la ejecucin de mtodos, de
manera que si se produce un error tanto en
el servidor de bases de datos como en la
mquina virtual se realizan acciones de
recuperacin a un estado seguro.
Las transacciones son un tema optativo en
CLS y se estudiarn junto con las
Enterprise Java Beans (EJB).

Ciclo de vida completo


de entidades

You might also like