[ES] Manejadores de persistencia

56
Let's Rock Java Fundamentos de Java Enterprise Edition con JDeveloper Eudris Cabrera Rodriguez Ingeniero Telemático Senior Software Developer Skype:eudriscabrera LinkedIn:http://www.linkedin.com/in/eudriscabrera Diciembre 2011, Santiago de los Caballeros, R. D.

description

Conocer los conceptos fundamentales sobre los manejadores de persistencia en Java y su implementación en una aplicación empresarial Java (JEE).

Transcript of [ES] Manejadores de persistencia

Page 1: [ES] Manejadores  de persistencia

Let's Rock Java

Fundamentos de Java Enterprise Edition con JDeveloper

Eudris Cabrera Rodriguez

Ingeniero TelemáticoSenior Software DeveloperSkype:eudriscabreraLinkedIn:http://www.linkedin.com/in/eudriscabrera Diciembre 2011, Santiago de los Caballeros, R. D.

Page 2: [ES] Manejadores  de persistencia

Objetivos

Aprender los conceptos fundamentales sobre los manejadores de persistencia en Java y su implementación en una aplicación empresarial Java (JEE).

Page 3: [ES] Manejadores  de persistencia

Agenda○ Manejadores de persistencia

■ Conceptos y Definiciones■ Introdución a Java Persistence API (JPA)■ Conceptos Avanzados de Java Persistence API

(JPA)○ Persistencia en la capa web○ JSTL (JavaServer pages Standard Tag Library)

Page 4: [ES] Manejadores  de persistencia

Conceptos y definiciones

En Java solucionamos problemas de negocio a través de objetos, los cuales tienen estado y comportamiento.

Sin embargo, las bases de datos relacionales almacenan la información mediante tablas, filas, y columnas, de manera que para almacenar un objeto hay que realizar una correlación entre el sistema orientado a objetos de Java y el sistema relacional de nuestra base de datos.

JPA (Java Persistence API - API de Persistencia en Java) es una abstracción sobre JDBC que nos permite realizar dicha correlación de forma sencilla, realizando por nosotros toda la conversión entre nuestros objetos y las tablas de una base de datos.

Page 5: [ES] Manejadores  de persistencia

Conceptos y definiciones

Esta conversión se llama ORM (Object Relational Mapping - Mapeo Relacional de Objetos), y puede configurarse a través de metadatos (mediante xml o anotaciones).

Por supuesto, JPA también nos permite seguir el sentido inverso, creando objetos a partir de las tablas de una base de datos, y también de forma transparente. A estos objetos los llamaremos desde ahora entidades (entities).

JPA establece una interface común que es implementada por un proveedor de persistencia de nuestra elección (como Hibernate, Eclipse Link, etc), de manera que podemos elegir en cualquier momento el proveedor que más se adecue a nuestras necesidades. Así, es el proveedor quién realiza el trabajo, pero siempre funcionando bajo la API de JPA.

Page 6: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)UNA ENTIDAD SIMPLE:

import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;

@Entitypublic class Pelicula {

@Id@GeneratedValueprivate Long id;private String titulo;private int duracion;

// Getters y Setters

}

Page 7: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

Las entidades suelen ser POJOs. La clase Pelicula se ha anotado con @Entity, lo cual informa al proveedor de persistencia que cada instancia de esta clase es una entidad. Para ser válida, toda entidad debe:

- Tener un constructor por defecto- Ser una clase de primer nivel (no interna)- No ser final- Implementar la interface java.io.Serializabe si es accedida remotamente

La configuración de mapeo puede ser especificada mediante un archivo de configuración XML, o mediante anotaciones. A esta configuración del mapeo la llamamos metadatos.

Page 8: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

IDENTIDAD:Todas las entidades tienen que poseer una identidad que las diferencie del resto, por lo que deben contener una propiedad marcada con la anotación @Id (es aconsejable que dicha propiedad sea de un tipo que admita valores null, como Integer en lugar de int).

CONFIGURACIÓN POR DEFECTO :JPA aplica a las entidades que maneja una configuración por defecto, de manera que una entidad es funcional con una mínima cantidad de información (las anotaciones @Entity y @Id en nuestro caso).

Page 9: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

Con esta configuración por defecto, todas las entidades del tipo Pelicula serán mapeadas a una tabla de la base de datos llamada PELICULA, y cada una de sus propiedades será mapeada a una columna con el mismo nombre (la propiedad id será mapeada en la columna ID, la propiedad título será mapeada en la columna TITULO, etc).

Sin embargo, no siempre es posible ceñirse a los valores de la configuración por defecto: imaginemos que tenemos que trabajar con una base de datos heredada, con nombres de tablas y filas ya definidos.

Page 10: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

En ese caso, podemos configurar el mapeo de manera que se ajuste a dichas tablas y filas:

@Entity@Table(name = "TABLA_PELICULAS")public class Pelicula { @Id @GeneratedValue @Column(name = "ID_PELICULA") private Long id; ...}

Page 11: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

La anotación @Table nos permite configurar el nombre de la tabla donde queremos almacenar la entidad mediante el atributo name.

Así mismo, mediante la anotación @Column podemos configurar el nombre de la columna donde se almacenará una propiedad, si dicha propiedad puede contener un valor null, etc.

Page 12: [ES] Manejadores  de persistencia

LET'S CODE !!!

Page 13: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

LECTURA TEMPRANA Y LECTURA DEMORADA

JPA nos permite leer una propiedad desde la base de datos la primera vez que un cliente intenta leer su valor (lectura demorada). Esto puede ser útil si la propiedad contiene un objeto de gran tamaño:@Basic(fetch = FetchType.LAZY)private Imagen portada;

El comportamiento por defecto de la mayoría de tipos Java es el contrario (lectura temprana). Este comportamiento, a pesar de ser implícito, puede ser declarado explícitamente de la siguiente manera:@Basic(fetch = FetchType.EAGER)private Imagen portada;

Page 14: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

ASOCIACIONESCuando queremos mapear colecciones de entidades, debemos usar asociaciones. Estas asociaciones pueden ser de dos tipos:

- Asociaciones unidireccionales- Asociaciones bidireccionales

Las asociaciones unidireccionales reflejan un objeto que tiene una referencia a otro objeto (la información puede viajar en una dirección).

Por el contrario, las asociaciones bidireccionales reflejan dos objetos que mantienen referencias al objeto contrario (la información puede viajar en dos direcciones).

Page 15: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)Además del concepto de dirección, existe otro concepto llamado cardinalidad, que determina cuántos objetos pueden haber en cada extremo de la asociación.

Page 16: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)ASOCIACIONES UNIDIRECCIONALES

@Entitypublic class Cliente {

@Id@GeneratedValueprivate Long id;@OneToOneprivate Direccion

direccion;

// Getters y setters}

@Entitypublic class Direccion {

@IdGeneratedValueprivate Long id;private String calle;private String ciudad;private String pais;private Integer

codigoPostal;

// Getters y setters}

Page 17: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)Otro tipo de asociación muy común es la de tipo uno-a-muchos (one-to-many) unidireccional.

@Entitypublic class Cliente {

@Id@GeneratedValueprivate Long id;@OneToManyprivate List direcciones;

// Getters y setters

}

Page 18: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)ASOCIACIONES BIDIRECCIONALES

En las asociaciones bidireccionales, ambos extremos de la relación mantienen una referencia al extremo contrario.

En este caso, el dueño de la relación debe ser especificado explícitamente, de manera que JPA pueda realizar el mapeo correctamente.

Page 19: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)Ejemplo de bidireccionalidad en una relación de tipo uno-a-uno

@Entitypublic class Mujer {

@Id@GeneratedValueprivate Long id;@OneToOneprivate Marido marido;

// Getters y setters

}

@Entitypublic class Marido {

@Id@GeneratedValueprivate Long id;@OneToOne

(mappedBy = "marido")private Mujer mujer;

}

Page 20: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

PERSISTENCIA :El concepto de persistencia implica el hecho de almacenar nuestras entidades (objetos Java de tipo POJO) en un sistema de almacenamiento, normalmente una base de datos relacional (tablas, filas, y columnas).

Más allá del proceso de almacenar entidades en una base de datos, todo sistema de persistencia debe permitir recuperar, actualizar y eliminar dichas entidades. Estas cuatro operaciones se conocen como operaciones CRUD (Create, Read, Update, Delete - Crear, Leer, Actualizar, Borrar). JPA maneja todas las operaciones CRUD a través de la interface EntityManager.

Page 21: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)PERSISTIR UNA ENTIDAD :public class Main {

public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("introduccionJPA"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); Pelicula pelicula = new Pelicula(); pelicula.setTitulo("Pelicula uno"); pelicula.setDuracion(142); tx.begin(); try { em.persist(pelicula); tx.commit(); } catch(Exception e) { tx.rollback() }

em.close(); emf.close();

}}

Page 22: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

LEER UNA ENTIDAD Leer una entidad previamente persistida en la base de datos para construir un objeto Java. Podemos llevar a cabo de dos maneras distintas:

- Obteniendo un objeto real- Obteniendo una referencia a los datos persistidos

De la primera manera, los datos son leídos (por ejemplo, con el método find()) desde la base de datos y almacenados en una instancia de la entidad:

Pelicula p = em.find(Pelicula.class, id);

Page 23: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

La segunda manera de leer una entidad nos permite obtener una referencia a los datos almacenados en la base de datos, de manera que el estado de la entidad será leído de forma demorada (en el primer acceso a cada propiedad), no en el momento de la creación de la entidad:

Pelicula p = em.getReference(Pelicula.class, id);

Page 24: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

ACTUALIZAR UNA ENTIDAD

Mediante el método merge() de EntityManager podemos tener nuestra entidad gestionada y sincronizada

tx.begin();em.persist(pelicula);tx.commit();em.detach(pelicula);// otras operacionesem.merge(pelicula);

Page 25: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)ELIMINAR UNA ENTIDAD

em.remove(pelicula);

Cuando existe una asociación uno-a-uno y uno-a-muchos entre dos entidades, y eliminas la entidad dueña de la relación, la/s entidad/es del otro lado de la relación no son eliminada/s de la base de datos (este es el comportamiento por defecto), pudiendo dejar así entidades persistidas sin ninguna entidad que haga referencia a ellas.

Estas entidades se conocen como entidades huérfanas. Sin embargo, podemos configurar nuestras asociaciones para que eliminen de manera automática todas las entidades subordinadas de la relación

Page 26: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

OPERACIONES EN CASCADA

Este tipo de operaciones permiten establecer la forma en que deben propagarse ciertos eventos (como persistir, eliminar, actualizar, etc) entre entidades que forman parte de una asociación.

La forma general de establecer cómo se realizarán estas operaciones en cascada se define mediante el atributo cascade de las anotaciones de asociación:

@OneToOne(cascade = CascadeType.REMOVE)private Descuento descuento;

Page 27: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

CascadeType.PERSIST .REMOVE .MERGE .REFRESH .DETACH .ALL

La última constante, CascadeType.ALL, hace referencia a todas las posibles operaciones que pueden ser propagadas, y por tanto engloba en si misma el comportamiento del resto de constantes.

También podemos configurar varias operaciones en cascada de la lista superior usando un array de constantes CascadeType:

Page 28: [ES] Manejadores  de persistencia

Introdución a Java Persistence API (JPA)

@OneToOne(cascade = { CascadeType.MERGE, CascadeType.REMOVE, })private Descuento descuento;

Page 29: [ES] Manejadores  de persistencia

LET'S CODE !!!

Page 30: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

JPQL (Java Persistence Query Language - Lenguaje de Consulta de Persistencia en Java), un potente lenguaje de consulta orientado a objetos que va incluido con JPA.

JPQL BÁSICO

JPQL nos permite realizar consultas en base a multitud de criterios (como por ejemplo el valor de una propiedad, o condiciones booleanas), y obtener más de un objeto por consulta.

SELECT p FROM Pelicula p

Page 31: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

SENTENCIAS CONDICIONALES

El primero de ellos es el de consulta condicional, el cual es aplicado añadiendo la cláusula WHERE en nuestra sentencia JPQL.

SELECT p FROM Pelicula p WHERE p.duracion < 120

Page 32: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

PARÁMETROS DINÁMICOSPodemos añadir parámetros dinámicamente a nuestras sentencias JPQL de dos formas: por posición y por nombre. La sentencia siguiente acepta un parámetro por posición (?1):

SELECT p FROM Pelicula p WHERE p.titulo = ?1

Y la siguiente, acepta un parámetro por nombre (:titulo):

SELECT p FROM Pelicula p WHERE p.titulo = :titulo

Page 33: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

EJECUCIÓN DE SENTENCIAS JPQL

El lenguaje JPQL es integrado a través de implementaciones de la interface Query.

Dichas implementaciones se obtienen a través de nuestro querido amigo EntityManager, mediante diversos métodos de factoría. De estos, los tres más usados (y los únicos que explicaremos aquí) son:

createQuery(String jpql)createNamedQuery(String name)createNativeQuery(String sql)

Page 34: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

CONSULTAS CON NOMBRE (ESTÁTICAS)

Las consultas con nombre son diferentes de las sentencias dinámicas que hemos visto hasta ahora en el sentido de que una vez definidas, no pueden ser modificadas: son leídas y transformadas en sentencias SQL cuando el programa arranca por primera vez, en lugar de cada vez que son ejecutadas.

Este comportamiento estático las hace más eficientes, y por tanto ofrecen un mejor rendimiento. Las consultas con nombre son definidas mediante metadatos (recuerda que los metadatos se definen mediante anotaciones o configuración XML), como puedes ver en este ejemplo:

@Entity@NamedQuery(name="buscarTodos", query="SELECT p FROM Pelicula p")public class Pelicula { ... }

Page 35: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

CONSULTAS NATIVAS SQLEl tercer y último tipo de consultas que nos queda por ver requiere una sentencia SQL nativa en lugar de una sentencia JPQL:

String sql = "SELECT * FROM PELICULA";Query query = em.createNativeQuery(sql);

Page 36: [ES] Manejadores  de persistencia

Conceptos Avanzados de Java Persistence API (JPA)

Las consultas SQL nativas pueden ser definidas de manera estática como hicimos con las consultas con nombre, obteniendo los mismos beneficios de eficiencia y rendimiento. Para ello, necesitamos utilizar, de nuevo, metadatos:

@Entity@NamedNativeQuery(name=Pelicula.BUSCAR_TODOS, query="SELECT * FROM PELICULA")public class Pelicula {

public static final String BUSCAR_TODOS = "Pelicula.buscarTodos";

...}

Page 37: [ES] Manejadores  de persistencia

Persistencia en la capa Web

Page 38: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

A partir de JSP 1.2. se introduce un conjunto de librerías en la especificación, pasando a ser estándar.

JSTL consta de los siguientes grupos de etiquetas:

http://java.sun.com/jsp/jstl/corehttp://java.sun.com/jsp/jstl/xmlhttp://java.sun.com/jsp/jstl/fmthttp://java.sun.com/jsp/jstl/sql

Page 39: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

Expression language (EL)

JSTL define un lenguaje de expresiones (EL), que facilita enormemente el tratamiento de información.

Las expresiones se indican de la forma ${expresion).

Page 40: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

La librería core.

En las páginas que la usen deberemos incluir la siguiente directiva:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

out

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><br> <c:out value="1+2+3"/><br> <c:out value="${1+2+3}"/><br> <c:out value="${param.nombreParametro}"/><br> <c:out value="${sessionScope.variableDeSesion}"/>

Page 41: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

set

Guarda información en una variable, tiene los siguientes atributos:- var. Nombre de la variable- scope. Ámbito de la variable, admite los valores page, session y application.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:set var="variableDePagina" scope="page">Esta información se guarda en la página</c:set>

${variableDePagina}

Page 42: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

if

Procesa el cuerpo de la etiqueta si la condición se evalúa a cierto. La condición se indica en el atributotest.

Ejemplo:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:if test="${empty param.nombre}">Parámetro ‘nombre’ no definido.</c:if>

Page 43: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

choose, when y otherwise

Procesa condiciones múltiples, se procesa el cuerpo del primer when cuya condición especificada en elatributo test se evalúa a cierto.

Si ninguna de las condiciones se cumple, se procesa el cuerpo de otherwise en caso de que aparezca.

Page 44: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

Ejemplo:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:choose><c:when test="${empty param.nombre}">Parámetro ‘nombre’ no definido.</c:when><c:otherwise> Valor del parámetro ‘nombre’:${param.nombre}</c:otherwise></c:choose>

Page 45: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

forEach y forTokens.

forEach consta de los siguientes atributos:- items. Indica la colección sobre la que iterar- var. Indica el nombre de la variable donde se guardará el elemento en curso.- varStatus. Indica el nombre de la variable donde se guardará el estado de la iteración.

En cada iteración, la variable indicada en var irá tomando el valor del elemento en curso.A través de la variable indicada en varStatus podemos acceder a las siguientes propiedades:

- index. Posición del elemento en curso (comienza con 0).- count. Número de iteraciones (comienza con 1).- first. Valor booleano que indica si es la primera iteración.- last. Valor booleano que indica si es la última iteración.

Page 46: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

forTokens permite partir una cadena en fragmentos y recorrer cada uno de éstos, consta de lossiguientes atributos:

- items. Cadena que se quiere tokenizar.- var. Indica el nombre de la variable donde se guardará el fragmento en curso.- delims. Cadena con todos los caracteres que actúan como delimitador.- varStatus. Indica el nombre de la variable donde se guardará el estado de la iteración.

Page 47: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

Ejemplo:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:forEach items="${header}" var="cabecera">${cabecera}</c:forEach>

<%String []cadenas={"uno","dos","tres"};pageContext.setAttribute("cadenas",cadenas);%>

<c:forEach items="${pageScope.cadenas}" var="cadena">${cadena}</c:forEach>

Page 48: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

<c:forEach items="${param}" var="parametro">Nombre: ${parametro.key}Valor: ${parametro.value}

</c:forEach>

<c:forTokens items="cero, uno, dos, tres, cuatro, cinco"var="token" varStatus="status" delims=",">${status.index}.- ${token}</c:forTokens>

Page 49: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

redirect

Redirige a la dirección especificada en el atributo url, y aborta el procesamiento de la página actual.

Ejemplo:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:if test="${param.clave!=’secreto’}"><c:redirect url="login.jsp"/></c:if>

Page 50: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

Control de errores con catch

Con <c:catch> podemos capturar excepciones, sin que se aborte la ejecución de la página alproducirse un error.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:catch var="error01"><%=Integer.parseInt(request.getParameter("parametro"))%></c:catch><c:if test="${not empty error01}">Se produjo un error: ${error01}</c:if>

Page 51: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

La librería formatting

Contiene etiquetas que realizan diversas funciones relacionadas con formato y localización,comentamos únicamente formatDate y formatNumber.

La directiva para poder utilizarla es:<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

Page 52: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

formatDate

Permite formatear fechas. Tiene, entre otros, los siguientes atributos:- type. Permite los valores time (sólo hora), date (sólo fecha) y both (ambos). El valor por defecto es date.-pattern. Permite controlar el formato, podemos ver cómo estructurarlo en la clasejava.text.SimpleDateFormat del API de Java.value. La fecha en sí o la variable que la contiene.

Page 53: [ES] Manejadores  de persistencia

JSTL (JavaServer pages Standard Tag Library)

Ejemplo

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%><%pageContext.setAttribute("fecha",new java.util.Date());%>

Hoy es:<fmt:formatDate value="${pageScope.fecha}"pattern="dd/MM/yyyy"/>

Page 54: [ES] Manejadores  de persistencia

LET'S CODE !!!

Page 55: [ES] Manejadores  de persistencia

PREGUNTAS ?

Page 56: [ES] Manejadores  de persistencia

WE ROCK JAVA !!!