You are on page 1of 16

JPA: Introduccin1 Gua de Laboratorio

Esta gua se complementa con la orientacin en clase por parte del docente y las actividades propias del alumno.

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 1

Referencias
STRUTS Pgina Oficial
http://struts.apache.org/

Descargas
http://struts.apache.org/download.cgi Descargar archivo que contiene las librerias necesarias para utilizar struts 2.1.8.1.

JPA Pgina Oficial del Java EE


http://www.oracle.com/technetwork/java/javaee/overview/index.html

Tutorial JPA
http://java.sun.com/javaee/5/docs/tutorial/doc/bnbpz.html

Implementacin de JPA
http://www.eclipse.org/eclipselink/jpa.php
Ir a la seccin Downloads, Previous Releases y descargar archivo del link EclipseLink 2.0.1 Installer Zip (27 MB) que contiene las libreras necesarias para utilizar JPA

IDE de desarrollo

Eclipse Helios: http://www.eclipse.org/downloads/packages/release/helios/r Contenedor Web Apache Tomcat 7.0: http://tomcat.apache.org/ Base de Datos MySql Community Server http://www.mysql.com/downloads/mysql/ Lenguaje de Programacin Java JSE 6
http://java.sun.com/javase/downloads/widget/jdk6.jsp Framework JPA Ing. Luis H. Garca P. Ing. William Marquina Pgina 2

JPA
Java Persistence API, siglas de JPA, es un API de persistencia para la plataforma JAVA que aplica el Mapeo Relacional Objeto (ORM: Object-Relational Mapping) permitiendo interactuar con bases de datos relacionales sin perder las ventajas de la orientacin a objetos. Objetivo: Implementar una aplicacin web bsica utilizando las principales caractersticas del framework JPA. Configuracin Archivo persistence.xml y anotaciones Componentes Clases de entidad y uso de EntityManager. Implementacin EclipseLink

Aplicacin web bsica con JPA 1.0 Se probar una aplicacin web con los componentes mnimos para el correcto funcionamiento del framework JPA versin 1.0

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 3

PASO 1: Importar el proyecto web clase_jpa_inicio.war Vamos a aprender a utilizar JPA haciendo uso de un proyecto base de la plantilla del curso propuesta. Este proyecto ya tiene implementado el mantenimiento de la tabla Usuario en las capas de presentacin y negocio. La capa de datos(persistencia) la vamos a implementar con JPA. Los componentes de JPA estarn ubicados dentro del paquete edu.plantilla,persistencia.

Las libreras jar necesarias son: eclipselink.jar y javax.persistence_1.0.0.jar. NOTAS: 1) Obsrvese que el paquete persistencia tiene dos subpaquetes: entidad: Contiene clases de entidad que tpicamente representan una tabla relacional de una base de datos. Una instancia de clase representar una fila de una tabla relacional. jpa: Contiene clases donde se implementar las funcionalidades de acceso a base de datos y operaciones CRUD con las tablas relacionales. 2) persistence.xml es el archivo de configuracin de los componentes que utilizar JPA.

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 4

PASO 2: Creacin de una clase de entidad Primero debemos configurar el aplicativo para que utilize JPA. En el archivo persistence.xml aadir:
<?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/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="AppJPA" > <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <!-- <class>edu.plantilla.persistencia.entidad.nombreClase</class> --> <properties> <property name="eclipselink.jdbc.batch-writing" value="JDBC"/> <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306/demodbjpa"/> <property name="eclipselink.jdbc.user" value="root"/> <property name="eclipselink.jdbc.password" value="root"/> </properties> </persistence-unit> </persistence>

Donde: persistence-unit: Indica la unidad de persistencia a utilizar para una base de datos. provider: Indica el proveedor de la implementacin del API JPA, en este caso eclipseLink. class: Indica clase de entidad que ser utilizada en la unidad de Persistencia. properties: Se indican las propiedades de conexin a base de datos. PASO 3: Creacin de una clase de entidad Una clase de entidad representa una tabla relacional, por lo cual debemos definirle todas las caractersticas que la tabla presente: nombre de tabla, columnas, tipos de datos de cada columna, llave primaria y relaciones con otras tablas principalmente. Ejemplo: Se tiene en el schema demodbjpa la Tabla Usuario, la cual NO tiene relacin con otra tabla segn el script:
create database demodbjpa; use demodbjpa; CREATE TABLE t_usuario( usuario varchar(10) NOT NULL, password varchar(10) NULL, nombre varchar(50) NULL ); ALTER TABLE t_usuario ADD PRIMARY KEY (usuario);

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 5

Crear en el paquete edu.plantilla.persistencia.entidad una clase con nombre Usuario

Declarar los atributos respecto a las columnas de la tabla usuario: private String usuario; private String contrasena; private String nombre; Generar los mtodos getter/setter para cada atributo.

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 6

Ahora vamos a utilizar @Anotaciones para completar el mapeo relacional objeto:


package edu.plantilla.persistencia.entidad; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import

javax.persistence.Table; 1

@Entity @Table(name="t_usuario") public class Usuario { @Id private String usuario; @Column(name="password") private String contrasena; @Column private String nombre; public String getUsuario() { return usuario; } public void setUsuario(String usuario) { this.usuario = usuario; } public String getContrasena() { return contrasena; } public void setContrasena(String contrasena) { this.contrasena = contrasena; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } }

NOTAS: 1) Toda clase de entidad debe utilizar la anotacin @Entity, la cual indica que la clase representa una tabla relacional. En caso el nombre de la tabla y el nombre de la clase sean idnticos basta con utilizar esa anotacin. Solo en en caso que el nombre de la clase sea distinto al nombre de la tabla, se debe utilizar la anotacin @Table con el atributo name (name="") , para indicar el nombre de la tabla que la clase representa.

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 7

2)

Se observa los 3 atributos que representa a las columnas de las tablas con el tipo de dato que le corresponda a cada uno. @Column: Sirve para indicar que el atributo es una columna. Si la columna tiene el mismo nombre que el atributo, el mapeo es automtico. Si la columna no tiene el mismo nombre, hay que utilizar la anotacin @Column e indicar el nombre de la columna en el atributo name @Id: Sirve para indicar el atributo que representa la llave primaria de la tabla.

Ya hemos terminado el mapeo relacional objeto de la tabla Usuario.

PASO 4: Registro de una clase de entidad Ahora vamos a registrar la clase en la unidad de persistencia. Abrir archivo persistence.xml y aadir lo resaltado en amarillo:
<?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/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="AppJPA" > <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>edu.plantilla.persistencia.entidad.Usuario</class> <properties> <property name="eclipselink.jdbc.batch-writing" value="JDBC"/> <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306/demodbjpa"/> <property name="eclipselink.jdbc.user" value="root"/> <property name="eclipselink.jdbc.password" value="root"/> </properties> </persistence-unit> </persistence>

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 8

PASO 4: Uso de clase de entidad Vamos a implementar las operaciones CRUD con la tabla Usuario haciendo uso de JPA y la clase entidad Usuario. Crear en el paquete edu.plantilla.persistencia.jpa una clase con nombre UsuarioJPA

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 9

Aadir el cdigo base para este tipo de clase:


package edu.plantilla.persistencia.jpa; import import import import import javax.persistence.EntityManager; javax.persistence.EntityManagerFactory; javax.persistence.Persistence; javax.persistence.Query; org.apache.commons.beanutils.BeanUtils;

import edu.plantilla.bean.UsuarioDTO; import edu.plantilla.persistencia.entidad.Usuario;

public class UsuarioJPA { private static UsuarioJPA usuarioJPA; public static UsuarioJPA getInstance(){ if(usuarioJPA==null) usuarioJPA=new UsuarioJPA(); return usuarioJPA; }

public Usuario copiarPropiedadesAEntidad(UsuarioDTO usuarioDTO) throws Exception{ Usuario entidad=new Usuario(); BeanUtils.copyProperties( entidad,usuarioDTO); return entidad; } /* * Referenciamos a nuestra unidad de persistencia * AppJPA para gestionar nuestras entidades */ EntityManagerFactory fabrica= Persistence.createEntityManagerFactory("AppJPA");

NOTAS: 1) Permite utilizar una nica instancia de la clase para todo el aplicativo. 2) Mtodo utilitario para copiar los valores de las propiedades del DTO recibido a las propiedades del mismo nombre de la ENTIDAD a utilizar. IMPORTANTE: -Los objetos que se transportan entre capas son los DTO. -Los objetos que se utilizan en la capa de datos(persistencia) son las clases ENTIDAD, las cuales tiene configurado el mapeo relacional-objeto. -Por ello cuando un DTO es enviado a la capa de datos, es necesario copiar los valores del DTO a la ENTIDAD para poder utilizar JPA y acceder a bases de datos. Por estndar en el curso, los atributos del DTO deben ser iguales a los de la Entidad 3) Obtiene fabrica de recursos configurada en una unidad de persistencia. En este caso AppJPA
Pgina 10

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

PASO 5: Implementamos las operaciones del CRUD


public void insertar(UsuarioDTO usuarioDTO) throws Exception { Usuario entidad=copiarPropiedadesAEntidad(usuarioDTO); //1.Creamos instancia del EntityManager EntityManager em=fabrica.createEntityManager(); try{ //2.inicia la transaccin em.getTransaction().begin(); //3.ejecuta las operaciones em.persist(entidad); em.flush(); //4.ejecuta commit a la transaccin em.getTransaction().commit(); }finally { //5.cierra el EntityManager em.close(); } } public void actualizar(UsuarioDTO usuarioDTO) throws Exception { Usuario entidad=copiarPropiedadesAEntidad(usuarioDTO); EntityManager em=fabrica.createEntityManager(); try{ em.getTransaction().begin(); em.merge(entidad); em.flush(); em.getTransaction().commit(); }finally { em.close(); } } public void eliminar(UsuarioDTO usuarioDTO) throws Exception { EntityManager em=fabrica.createEntityManager(); try{ em.getTransaction().begin();
Usuario entidad=(Usuario)em.find(Usuario.class,usuarioDTO.getUsuario());

em.remove(entidad); em.flush(); em.getTransaction().commit(); }finally { em.close(); } }

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 11

Donde: Mtodo insertar: -em.persist(entidad): Genera un insert a la tabla relacional mapeada con los datos del objeto. Mtodo actualizar: -em.merge(entidad): Genera un update a la tabla relacional mapeada con los datos del objeto. Mtodo eliminar: -Es necesario primero realizar una bsqueda por llave primaria para asociar el objeto entidad a la transaccin con JPA -em.remove(entidad): Genera un delete a la tabla relacional mapeada con los datos del objeto. IMPORTANTE: -Asegrense que los objetos entidad fueron cargados con todos los valores necesarios en sus atributos antes de ejecutar las transacciones, de lo contrario puede dar error al momento de ejecutarlas.

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 12

En el caso de consultas:
public UsuarioDTO buscarXId(UsuarioDTO usuarioDTO) throws Exception{ Usuario entidad=copiarPropiedadesAEntidad(usuarioDTO); EntityManager em=fabrica.createEntityManager(); try{ em.getTransaction().begin(); Object o=(Object)em.find(Usuario.class, entidad.getUsuario()); if(o!=null){ entidad=(Usuario)o; BeanUtils.copyProperties( usuarioDTO,entidad); } em.getTransaction().commit(); }finally { em.close(); } return usuarioDTO; } public List<UsuarioDTO> buscarXCriterio(UsuarioDTO usuarioDTO) throws Exception{ List<UsuarioDTO> listaDTO=new Vector<UsuarioDTO>(); EntityManager em=fabrica.createEntityManager(); try{ em.getTransaction().begin(); String query="SELECT o FROM Usuario o "; Query emquery=em.createQuery(query); List<Usuario> listaEntidad=emquery.getResultList(); //Recorremos listado de entidades Iterator it=listaEntidad.iterator(); while(it.hasNext()){ Usuario entidad=(Usuario)it.next(); //Copiamos valores de entidad al DTO //Aadimos dto a listado de DTO usuarioDTO=new UsuarioDTO(); BeanUtils.copyProperties(usuarioDTO,entidad); listaDTO.add(usuarioDTO); } em.getTransaction().commit(); }finally { em.close(); } //Retornamos al servicio listado de DTO. return listaDTO; }

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 13

Mtodo buscarXId
Bsquedas por llave primaria

-em.find(ClaseEntidad.class, valorLlavePrimaria): Realiza una bsqueda por llave primaria en la tabla que representa la ClaseEntidad. Ejemplo:
Object o=(Object)em.find(Usuario.class, entidad.getUsuario());

-Este tipo de bsqueda devuelve un nico objeto, el cual de no ser nulo hay que castearlo a la clase ENTIDAD correspondiente.
if(o!=null) entidad=(Usuario)o;

IMPORTANTE: -Los objetos que se transportan entre capas son los DTO, por ello este mtodo devuelve un DTO a la capa de Negocio, previa copia de propiedades de la ClaseEntidad al DTO:
BeanUtils.copyProperties( usuarioDTO,entidad);

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 14

Mtodo buscarXCriterio: Bsquedas por criterio -Este tipo de bsqueda requiere el uso de Java Persistence Query Languaje. Es un lenguaje de consulta, similar al SQL, con la diferencia que trabaja con objetos directamente. String query="SELECT o FROM ClaseEntidad o "; -La consulta es de tipo String y para ejecutarla, debemos crearla y guardarla en un objeto de tipo Query String query="SELECT o FROM Usuario o "; Query emquery=em.createQuery(query); -A diferencia de la bsqueda por llave primaria, cuando usamos JPQL, podemos obtener ms de una instancia de objetos al realizar una operacin de consulta. Por ejemplo ejecutamos un query con el mtodo getResultList. List lista=(Vector<Usuario>)emquery.getResultList(); El resultado lo almacenamos en un listado con el tipo de ClaseEntidad correspondiente. IMPORTANTE: -Los objetos que se transportan entre capas son los DTO, por ello este mtodo devuelve un listado de DTO a la capa de Negocio, previa copia de propiedades de la ClaseEntidad al DTO.
Ejemplo: //Recorremos listado de entidades Iterator it=listaEntidad.iterator(); while(it.hasNext()){ Usuario entidad=(Usuario)it.next(); //Copiamos valores de entidad al DTO //Aadimos dto a listado de DTO usuarioDTO=new UsuarioDTO(); BeanUtils.copyProperties(usuarioDTO,entidad); listaDTO.add(usuarioDTO); }

-Tambin se puede utilizar JPQL para realizar actualizaciones eliminaciones masivas.

PASO 6: Ejecutar la aplicacin PASO 7: Excelente!, ha culminado de probar exitosamente la aplicacin web

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 15

CASO PROPUESTO PARA DESARROLLO EN CLASE


Ahora que ya hemos visto como utilizar JPA, importemos la ltima versin del proyecto plantilla que vimos en la anterior clase e implementemos la capa de persistencia(datos) ahora con JPA.

LA PRXIMA CLASE EXPLICAREMOS COMO UTILIZAR JPA CON TABLAS RELACIONADAS Y LLAVES FORNEAS.

Framework JPA Ing. Luis H. Garca P. Ing. William Marquina

Pgina 16