Desarrollo de Aplicaciones Web I

2

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

3

ÍNDICE
Presentación Red de contenidos Unidad de aprendizaje 1: Modelo Vista Controlador – Patrón MVC
1.1 Tema 1

Página

5 6

: Fundamentos de Struts 2

9 9 13 29 51 63

1.1.1. : Arquitectura y Configuración de aplicaciones 1.1.2. : La clase Action 1.1.3. : Librerías de etiquetas de Struts 2 1.1.4. : Internacionalización – I18N 1.2 Tema 2

: Acceso optimizado a base de datos y otras características Struts 2

1.2.1. : Uso de un pool de conexiones para acceso a la fuente

63

de datos
1.2.2. : Librería de Etiquetas de Struts 2 – Principales

72

componentes
1.2.3. : Patrón Composite View – Struts 2 Tiles

87

Unidad de aprendizaje 2: Persistencia de datos – Framework IBATIS
2.1 Tema 3

: Introducción a IBATIS

101 101 110

2.1.1. : IBATIS – Introducción 2.1.2. : Operaciones básicas de acceso a base de datos con

IBATIS
2.2 Tema 4

: Otras operaciones con IBATIS

119 119 128

2.2.1. : Otras operaciones y características de IBATIS 2.2.2. : Tópicos avanzados de IBATIS e Integración con

Struts 2

Unidad de aprendizaje 3: Reportes en Sistemas empresariales
3.1 Tema 5

: Reportes con JasperReport

139

CIBERTEC

CARRERAS PROFESIONALES

2 Tema 6 : Struts 2 y JasperReport 142 142 157 167 172 3.4 3. : Diseño e implementación de reportes con la 141 herramienta Ireport 3.1.1.2. : Integración de Struts 2 y JasperReport Anexo 1 Anexo 2 Anexo 3 CARRERAS PROFESIONALES CIBERTEC .1.

El manual para el curso ha sido diseñado bajo la modalidad de unidades de aprendizaje. Luego. De esta manera. continúa con la presentación del Framework MVC Struts 2. hallará los logros. Es práctico y desarrollado en laboratorio.DESARROLLO DE APLICACIONES WEB I 5 PRESENTACIÓN Desarrollo de Aplicaciones Web I pertenece a la línea de Programación y Desarrollo de Aplicaciones. las que se desarrollan durante semanas determinadas. se desarrollan conceptos de persistencia de datos utilizando para ello el Framework IBATIS. el cual será ampliamente desarrollado. Se profundiza en sus principales características y componentes. el lenguaje jasperReport e integrándolos a aplicaciones web creadas con Struts 2. Por último. Es un curso de especialidad sólo en la carrera de Computación e Informática. se inicia con el reconocimiento de los principales patrones de arquitectura de software. que debe desarrollar. destacándose el patrón Model View Controller (MVC). utilizando la herramienta IReport. En cada una de ellas. Por último. los subtemas. El curso es eminentemente práctico y se desarrolla íntegramente en laboratorio. CIBERTEC CARRERAS PROFESIONALES . Después. Permite al estudiante concretizar proyectos informáticos web. y los contenidos. consolida conocimientos de diversos cursos de especialidad. se concluye con la elaboración de reportes empresariales. que debe alcanzar al final de la unidad. el tema tratado. En primer lugar. que le permitirán reforzar lo aprendido en la clase. aplicando conocimientos previos aprendidos en diferentes cursos y poniendo en práctica la teoría adquirida. es decir. Se implementarán soluciones web que utilizarán los Frameworks Struts 2 e IBATIS en forma combinada. encontrará las actividades que deberá desarrollar en cada sesión.

6

RED DE CONTENIDOS

Desarrollo de Aplicaciones Web 1

Modelo Vista Controlador – Patrón MVC

Persistencia de datos – Framework IBATIS

Reportes en sistemas empresariales

Fundame ntos de Struts 2

Otras Características Struts 2

Introducción a IBATIS

Otras operaciones IBATIS

Tema 5 JasperReport

Tema 6 Struts 2 y Jasper

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

7

UNIDAD DE APRENDIZAJE

1

MODELO VISTA CONTROLADOR – PATRÓN MVC
LOGRO DE LA UNIDAD DE APRENDIZAJE
• Al finalizar la unidad, el alumno, utilizando el framework MVC STRUTS 2, implementa una aplicación web que contenga, en su estructura, el componente Action, las principales etiquetas del framework y acceso a base de datos a través de un pool de conexiones. Al finalizar la unidad, el alumno se integra a un equipo de trabajo que refleja en su estructura los roles de un equipo de proyecto de desarrollo de software.

TEMARIO 1.1 Tema 1 : Fundamentos de Struts 2 1.1.1. : Arquitectura y Configuración de aplicaciones 1.1.2. : La clase Action 1.1.3. : Librerías de etiquetas de Struts 2 1.1.4. : Internacionalización – I18N

1.2 Tema 2 : Acceso optimizado a base de datos y otras características de Struts 2 1.2.1. : Uso de un Pool de conexiones para acceso a la fuente de datos 1.2.2. : Librería de Etiquetas de Struts 2 – Principales componentes. 1.2.3. : Patrón Composite View – Struts 2 Tiles

ACTIVIDADES PROPUESTAS
• Los alumnos implementan una aplicación web básica, utilizando las principales características del framework MVC Struts 2.

CIBERTEC

CARRERAS PROFESIONALES

8

1.1 Fundamentos de Struts 2
Struts 2 es un framework que implementa el patrón de arquitectura MVC en Java. Éste organiza de manera independiente las capas: Model (Objetos del Modelo del Negocio), View (interfaz con el usuario u otro sistema) y la capa Controller (controlador del flujo de la aplicación. Se muestra, a continuación, el esquema básico de funcionamiento de esta arquitectura. La capa Model en Struts 2 inicia con los componentes Action. Debajo de éstos, se tendrán diversos componentes: Services (Lógica pura de negocio) DAOs (objetos de persistencia de datos), entre otros. Se muestra, a continuación, el esquema básico de la arquitectura MVC implementado por el framework Struts 2.

Figura 1.1

Una característica típica de la capa View de Struts 2 es el uso de unos componentes especiales denominados Results. Éstos normalmente son representados por una página JSP; sin embargo, puede constituir, también, flujos de bytes, objetos del framework Tiles, etc.

1.1.1. Arquitectura y configuración de aplicaciones
La arquitectura MVC funciona en Struts 2 básicamente de la siguiente manera: a través de un navegador se genera una solicitud. Ésta es capturada por la capa Controller (implementada por el componente FilterDispathcher representado por un único filtro especializado). Este filtro analizará la solicitud y verificará si el componente invocado se

CARRERAS PROFESIONALES

CIBERTEC

Ejercicio 1: Aplicación web básica de Struts 2 Se probará una aplicación web con los componentes mínimos para el correcto funcionamiento del framework Struts 2.1. 1.1. a) Paso 1: mportar el archivo struts2-blank-2. tal como se muestra a continuación: 1 2 Notas: CIBERTEC CARRERAS PROFESIONALES . Éste tiene por defecto el nombre struts. que cuenta con las características mínimas para que pueda ser ejecutada. instanciará y/o utilizará diversos objetos de negocio para concretar la tarea solicitada. de importarla. se visualizará un proyecto web. la capa Controller derivará la respuesta generada a un objeto Result (normalmente una página JSP). Según el resultado que retorne el componente Action.war. Luego.1.xml.1.8.war Al descargar el framework struts2 .1.1. Esta aplicación viene empaquetada dentro del archivo struts2-blank-2.8. El componente invocado. normalmente un Action de Struts 2.se tendrá acceso a una aplicación web de prueba.DESARROLLO DE APLICACIONES WEB I 9 encuentra registrado en el archivo de configuración XML de Struts 2.1.

8. 2) Puede observar las librerías mínimas con las que todo proyecto basado en Struts 2 debería contar.apache. CARRERAS PROFESIONALES CIBERTEC .sun.4" xmlns="http://java.1.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts Blank</display-name> <filter> <filter-name>struts2</filter-name> <filter-class> org.w3.xml <?xml version="1.dispatcher.filter.html</welcome-file> </welcome-file-list> </web-app> 1 Notas: 1) Note el registro del filtro controlador del framework Struts 2. b) Paso 2: Revisar el archivo web. Se inicia esta sesión con el registro de la clase Action.struts2. se registrarán sus principales componentes. Este componente “atrapará” todas las solicitudes (request) generadas desde un cliente.xml.com/xml/ns/j2ee http://java.jar.10 1) El principal archivo de configuración del Framework es el archivo struts.1.sun. Dentro de ellas.ng.0" encoding="UTF-8"?> <web-app id="WebApp_9" version="2.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java. En él.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index. dado que tiene como alias /*. destaca el archivo struts2-core-2.

DESARROLLO DE APLICACIONES WEB I 11 c) Paso 3: Ejecutar la aplicación d) Paso 4: ¡Excelente!.1. ha culminado el proceso de probar exitosamente la aplicación web struts2-blank-2.1 CIBERTEC CARRERAS PROFESIONALES .8.

Ejercicio 1: Funcionalidad de Logueo Versión 1 Se simulará la funcionalidad de logueo con los componentes básicos del framework Struts 2 y sin acceso a base de datos. apoya al framework determinando qué result será retornado en la respuesta que se genere a la solicitud realizada. La clase Action Un action es. Finalmente. a) Paso 1: Copiar las principales librerías y archivos configuración al proyecto web funcionalidadLogueov1_Inicial de 1 2 CARRERAS PROFESIONALES CIBERTEC . En primer lugar. Es el componente que interactúa con la capa controladora y la capa view. actúa como un transportador natural de datos entre el objeto request y los componentes de la capa view. esto gracias a las características de transferencia automática de datos que tiene struts 2 entre estos. recibe las solicitudes (request) enviadas por un cliente y realiza el trabajo inicial para atenderla.12 1. Un actions realiza básicamente tres pasos dentro de una aplicación web. un ejercicio. En segundo lugar. 1.2. Se detalla. en el cual se apreciarán los principales componentes de la arquitectura MVC utilizando Struts 2. en Struts 2. a continuación.1. el primer componente de la capa Model dentro de la arquitectura MVC.1.1.2.

filter.java. utilizando la vista Navigator. La clase LogueoAction debe contar con la siguiente lógica: CIBERTEC CARRERAS PROFESIONALES .StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> c) Paso 3: Crear el primer componente Struts 2 de la aplicación.xml <!-. dentro de él.dispatcher.apache.xml dentro de la carpeta src. 2) Distinga las principales librerías y archivos de configuración en las ubicaciones correctas: librerías en la carpeta lib y archivo de configuración struts.DESARROLLO DE APLICACIONES WEB I 13 Notas: 1) Observe que solo se puede copiar el archivo struts. b) Paso 2: Registrar el filtro controlador de Struts 2 dentro del archivo web.xml en la carpeta src junto a los archivos fuente. genere la clase LogueoAction. la clase LogueoAction 1 Notas: 1) Agregue el paquete aprendamos.registramos el filtro controlador de struts 2 --> <filter> <filter-name>struts2</filter-name> <filter-class> org.action y.ng.struts2.

clave = clave.jsp </result> Notas: 1) El “alias” de la clase action es logueo. return vista.jsp </result> >/bienvenida.14 package aprendamos. private String clave. Ya no invocará a la clase LogueoServlet sino a LogueoAction. public class LogueoAction { private String usuario.jsp. debe modificar el archivo logueo.xml 1 <package name="default" namespace="/" extends="struts-default"> <action name="logueo" class="aprendamos. CARRERAS PROFESIONALES CIBERTEC . public String getUsuario() { return usuario. } public String getClave() { return clave. } } d) Paso 4: Registrar la clase LogueoAction en el archivo struts.action.LogueoAction" > <result name="error" <result name="exito" </action> </package> >/logueo.usuario = usuario. por lo tanto.java.java. } public void setClave(String clave) { this. } public void setUsuario(String usuario) { this.action. } public String execute(){ String vista="exito".

Service y Business Delegate. f) Paso 6: ¡Bien!. ha culminado la funcionalidad de logueo versión 1 1. Ejercicio 2: Funcionalidad de Logueo Versión 2 Se efectúa la funcionalidad de logueo con los componentes básicos del framework e implementando los patrones de diseño DAO (Data Access Object).2.2. CIBERTEC CARRERAS PROFESIONALES .xml.1. Recuerde que en Struts 2 todas las solicitudes son atrapadas por el filtro controlador del framework. Éste invocará al action respectivo sobre la base del registro realizado en el archivo struts. a) Paso 1: Modificar la clase MySqlClienteDAO y verificar su correcta relación con las clases que implementan el patrón de diseño DAO.DESARROLLO DE APLICACIONES WEB I 15 e) Paso 5: Ejecutar la aplicación web 1 Notas: 1) Se puede observar en el url que el alias invocado es logueo.

setSexo(rs. Adicionalmente. etc. } CARRERAS PROFESIONALES CIBERTEC . Verifique si existe la interface ClienteDAO. objClienteDTO.setFecnac(rs. El patrón de diseño DAO (Data Access Object) permite que un componente pueda acceder a diferentes orígenes de datos de manera independiente y transparente. Microsoft SQL Server.getDouble(4)). recuperamos un regsitro if(rs. objClienteDTO.getString(1)). se cuentan con componentes DAO para acceder al motor de base de datos MySql. Complete el código con la lógica mostrada a continuación: //ejecutamos ResultSet rs=pst. objClienteDTO.setNombre(rs. } cn.setSueldo(rs. tales como Oracle.getDate(6)). En este proyecto.getString(5)).getString(2)). objClienteDTO. se debe crear un componente DAO.setUsuario(rs. . Ésta debe ser implementada por la clase MySqlClienteDAO: public interface ClienteDAO { public int registraCliente(ClienteDTO objCliente) throws Exception.setClave(rs. objClienteDTO. se podrían contar con DAOs para acceder a otros orígenes de datos.getString(3)). debe modificar el método buscaPorUsuario. //si hay datos. Por cada entidad dentro del modelo de datos.close().16 Dentro de la clase MySqlClienteDAO.next()){ objClienteDTO = new ClienteDTO(). objClienteDTO. public ClienteDTO buscaPorUsuario(String usuario) throws Exception. . archivos XML. .executeQuery().

DESARROLLO DE APLICACIONES WEB I 17 Una interface permite exponer “al mundo” las operaciones de la clase que la implementa. //public abstract ProductoDAO getProductoDAO(). // registramos nuestros daos public abstract ClienteDAO getClienteDAO(). } Verifique si la clase MySqlClienteDAO ha sido “registrada” en la “fábrica de fábricas” DAOFactory: public abstract class DAOFactory { public public public public public static static static static static final final final final final int int int int int MYSQL = 1. DB2 = 3. ORACLE = 2. public static DAOFactory getDAOFactory(int whichFactory){ switch(whichFactory){ case MYSQL: return new MySqlDAOFactory(). case XML: return new XmlDAOFactory(). CIBERTEC CARRERAS PROFESIONALES . XML = 5. case ORACLE: return new OracleDAOFactory(). // Ejemplo: //public abstract ArticuloDAO getArticuloDAO(). Verifique si MySqlClienteDAO es retornado por la fábrica de DAOs para MySql: public class MySqlDAOFactory extends DAOFactory { // Esta es una fabrica que crea DAOs especificos para Mysql @Override public ClienteDAO getClienteDAO() { // TODO Auto-generated method stub return new MySqlClienteDAO(). 1 // Existirá un método por cada DAO que pueda ser creado. SQLSERVER = 4.

buscaPorUsuario(cliente.18 Notas: 1) El registro de la clase MySqlClienteDAO es la creación de un método abstracto en la clase DAOFactory que retorna a la interface que implementa MySqlClienteDAO. // Referenciamos al dao de la entidad cliente ClienteDAO objClienteDAO = fabrica. public ClienteDTO validaUsuario(ClienteDTO cliente) throws Exception { // aqui podriamos tener mas logica return objClienteDAO.getDAOFactory(DAOFactory. b) Paso 2: Crear la clase LogueoService y la interface LogueoService_I 1 2 public class LogueoService implements LogueoService_I { // Referenciamos a la fabrica de daos para mysql DAOFactory fabrica = DAOFactory.MYSQL).getUsuario()). } } CARRERAS PROFESIONALES CIBERTEC .getClienteDAO().

Éste puede invocar a uno o más DAOs. en la programación. debe crear la interface LogueoService_I public interface LogueoService_I { public abstract ClienteDTO validaUsuario(ClienteDTO cliente) throws Exception. Representa. Debe “exponer” las operaciones de la clase LogueoService. por lo tanto.DESARROLLO DE APLICACIONES WEB I 19 Notas: 1) Agregue el paquete aprendamos. se debe implementar un servicio. 2) Un servicio es un componente. } c) Paso 3: Crear la clase PaqueteBusinessDelegate 1 CIBERTEC CARRERAS PROFESIONALES .java.action y dentro de él genere la clase LogueoAction. Por cada caso de uso de sistema identificado en la aplicación. el inicio de la lógica de negocio. que pertenece a la capa Model del patrón de diseño MVC.

mensaje = mensaje. private String mensaje.20 2 public class PaqueteBusinessDelegate { private PaqueteBusinessDelegate() { // TODO Auto-generated constructor stub } public static LogueoService_I getLogueoService(){ return new LogueoService(). public class LogueoAction { private String usuario. se debe tener un componente BusinessDelegate. private String clave.java. 2) Por cada paquete de un modelo de análisis. genere la clase PaqueteBusinessDelegate. } CARRERAS PROFESIONALES CIBERTEC . Genere. dentro de la clase LogueoAction. } public void setMensaje(String mensaje) { this. } // agregar aqui mas llamadas a otros servicios } Notas: 1) Dentro del paquete aprendamos.service. No debe olvidar crear los métodos setter y getter para el nuevo atributo. el atributo mensaje para poder visualizar posibles “mensajes de error” en la capa de presentación. d) Paso 4: Invocar los componentes de lógica de negocio. public String getMensaje() { return mensaje. y crear la sesión web. desde la clase LogueoService. Esta clase será invocada por los actions y retornará componentes tipo Service.

out. }else{ vista="error". } if(objUsuario!=null){ if(objUsuario. this. // invocamos a nuestro servicio (logica de negocio) LogueoService_I logueoservice = PaqueteBusinessDelegate. objUsuario). ClienteDTO objUsuario=null.validaUsuario(usuarioCandidato).println(this.getClave()). lasesion.setMensaje( "Lo sentimos. System.printStackTrace(). System. } }else{ vista="error". usuarioCandidato.setMensaje("Es una pena.getContext().out.put("b_usuario".DESARROLLO DE APLICACIONES WEB I 21 Agregue la lógica que permitirá validar los datos ingresados y almacenarlos en la sesión web.println(this. ClienteDTO usuarioCandidato= new ClienteDTO().equals(this. public String execute(){ String vista="exito".getLogueoService().println("dentro de nuestro primer action"). } return vista.setUsuario(this.getUsuario()).getSession().Object> lasesion= ActionContext. el usuario no existe!").getClave(). System. this. la clave es incorrecta"). } catch (Exception e) { // TODO Auto-generated catch block e.getUsuario()). try { objUsuario = logueoservice.out.getClave())){ // creamos la sesion web al estilo struts 2 Map<String. } CIBERTEC CARRERAS PROFESIONALES .

jsp para visualizar el mensaje de error definido en la clase LogueoAction. ingrese un usuario inválido. <tr> <td class="error general"> <!-.22 Recuerde que debe utilizar Expression Language (EL) en el JSP logueo.jsp para visualizar los datos del cliente cargados en la sesión web. CARRERAS PROFESIONALES CIBERTEC .podemos visualizar el mensaje de error usando EL --> ${requestScope. <tr> <td class="error general"> <!-.mensaje} </td> </tr> e) Paso 5: Ejecutar la aplicación Primero.mensaje} </td> </tr> Recuerde que debe utilizar Expression Language (EL) en el JSP bienvenida.podemos visualizar el mensaje de error usando EL --> ${requestScope.

ingrese los datos correctamente. ingrese el usuario correcto.DESARROLLO DE APLICACIONES WEB I 23 Luego. pero la clave equivocada. ha culminado la funcionalidad de logueo versión 2 CIBERTEC CARRERAS PROFESIONALES . ¡Excelente!. Por último.

custom. a través de la key struts.resources.properties Puede agregar las keys correspondientes a los mensajes de error del logueo.custom.action.ui.24 1. struts. CARRERAS PROFESIONALES CIBERTEC . Se puede observar que.recursos.MisRecursos struts.i18n.i18n..extension=action. a través del uso de archivos de recursos y nuevas características del framework Struts 2.1. a) Paso 1: Definir el archivo de recursos para Struts 2 Se copia el archivo struts. Librerías de etiquetas de Struts 2 1. se define la ubicación del archivo de recursos. Ejercicio 1: Funcionalidad de Logueo Versión 3 Agregue una nueva funcionalidad al logueo implementado.3.3.1.resources=aprendamos.1.theme=simple struts.java.properties dentro de la carpeta src del proyecto.dudu b) Paso 2: Agregar nuevas keys al archivo de recursos MisRecursos.

. import java. . Esto permitirá incluir funcionalidad adicional dentro de la misma. .titulo = logueo. this. la clave ingresada no c) Paso 3: Referenciar las keys dentro de la clase LogueoAction Para poder referenciar las keys.action. public class LogueoAction extends ActionSupport { private String usuario.java.setMensaje( this.error.opensymphony.xwork2.usuario")) . import aprendamos. } .xwork2.usuario=Lo sentimos. this.java.Que facil es JEE :):) logueo. heredado de la clase ActionSupport.bean.ClienteDTO. . CIBERTEC CARRERAS PROFESIONALES .error.PaqueteBusinessDelegate.LogueoService_I. private String mensaje.clave=Es una pena. import com.service.java.ActionSupport.getText( "logueo.Map.mensaje. private String clave.setMensaje(this.error.error.opensymphony.service.getText("logueo. import aprendamos.mensaje.mensaje. . import aprendamos. Invoque el método getText.clave")). la clase LogueoAction debe heredar de la clase ActionSupport. el usuario ingresado no existe :( logueo.mensaje.java. } }else{ vista="error".DESARROLLO DE APLICACIONES WEB I 25 # Definiremos keys y sus respectivos valores # Una key es un identificador asociado a alguna descripcion #keys para el logueo : completar Pagina de Inicio .util. import com.ActionContext. }else{ vista="error". package aprendamos.

jsp Debe referenciar a la librería de etiquetas de struts 2. <%@ taglib prefix="s" uri="/struts-tags" %> Transforme las etiquetas html en sus equivalentes de Struts 2.usuario" /> </td> <td> <s:textfield name="cliente.mensaje} </td> </tr> <tr> <td > <fmt:message key="logueo.26 d) Paso 4: Modificar el JSP logueo.usuario" /> </td> </tr> <tr class="etiqueta" > <td > <fmt:message key="kclave" /> </td> <td> <s:password name="cliente.clave" /> </td> </tr> <tr> <td colspan="2" align="right" > <s:submit name="boton01" value="Ingresar" type="submit" /> </td> </tr> <tr> <td class="error general"> ${requestScope.imagen" /> </td> </tr> > </table> </s:form> CARRERAS PROFESIONALES CIBERTEC .png" </td> </tr> <tr class="etiqueta" > <td> <fmt:message key="logueo. <s:form action="logueo" method="post" > <table > <tr class="etiqueta" > <td colspan="2" > <img alt="El loguito" src="imagenes/logo_tiny.

public ClienteDTO getCliente() { return cliente. public String execute(){ String vista="exito". Notas: } if(objUsuario!=null){ 2 if(objUsuario. e) Paso 5: Referenciar a los campos cliente. } public void setCliente(ClienteDTO cliente) { this.clave dentro de la clase LogueoAction Agregue el atributo cliente en la clase LogueoAction. try { objUsuario = logueoservice.setUsuario(this.getCliente().printStackTrace(). public class LogueoAction extends ActionSupport { private ClienteDTO cliente=null. System.println("dentro de nuestro primer action"). System.out. ClienteDTO usuarioCandidato= new ClienteDTO(). usuarioCandidato.getUsuario()). 1 // invocamos a nuestro servicio (logica de negocio) LogueoService_I logueoservice = PaqueteBusinessDelegate. ClienteDTO objUsuario=null.validaUsuario(usuarioCandidato).out.cliente = cliente.println(this.getClave()).getCliente().out.println(this.usuario y cliente.equals(this.cliente.usuario y cliente. } catch (Exception e) { // TODO Auto-generated catch block e.getLogueoService().DESARROLLO DE APLICACIONES WEB I 27 Note que se han modificado los nombres de los campos usuario y clave por cliente.cliente.getUsuario()). System.clave.getClave().getClave())){ CIBERTEC CARRERAS PROFESIONALES . } Modifique el método execute.

Luego. Por último. pero la clave equivocada. f) Paso 6: Ejecutar la aplicación Primero. Esta vez invocando al método getCliente(). ingrese un usuario inválido. CARRERAS PROFESIONALES CIBERTEC . ingrese el usuario correcto.28 1) Los datos son obtenidos a partir del nuevo atributo cliente. 2) Se obtienen nuevamente los datos a partir del atributo cliente. ingrese los datos correctamente.

DESARROLLO DE APLICACIONES WEB I 29 g) Paso 7: ¡Muy buen trabajo! CIBERTEC CARRERAS PROFESIONALES .

30 1. haciendo uso de de las utilidades incluidas en el framework para procesar archivos (en el ejemplo la imagen del cliente) a través de un formulario HTML y gestionarlos dentro de la aplicación web implementada.sql.war web 1 Notas: 1) Note que. CARRERAS PROFESIONALES CIBERTEC .2.1. dentro del proyecto. a) Paso 1: Importar el proyecto FuncionalidadRegistraImagen_Inicial. cuenta con el script de base de datos FacilitoBaseDatos. se debe verificar que la tabla tbcliente cuenta con un tipo de dato adecuado para almacenar un archivo de cualquier modelo. Ejercicio 2: Funcionalidad Registro de cliente Se implementa la funcionalidad indicada. En él.3.

se almacenará la imagen asociada al cliente que registrará en su aplicación web. `foto` longblob DEFAULT NULL. `fecnac` datetime DEFAULT NULL. `clave` varchar(15) NOT NULL DEFAULT ''. CREATE TABLE `tbcliente` ( `nombre` varchar(100) DEFAULT NULL. --. USE facilito. PRIMARY KEY (`usuario`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1.Definition of table `tbcliente` -DROP TABLE IF EXISTS `tbcliente`. CIBERTEC CARRERAS PROFESIONALES . `usuario` varchar(15) NOT NULL DEFAULT ''. `sexo` char(1) DEFAULT NULL.DESARROLLO DE APLICACIONES WEB I 31 b) Paso 2: Verificar que la tabla tbcliente cuente con un campo de tipo longblog CREATE DATABASE IF NOT EXISTS facilito. 1 Notas: 1) Observe que. `sueldo` double DEFAULT NULL. en el campo “foto”.

.se habilita el formulario para soportar campos tipo File.32 c) Paso 3: Modificar el archivo nuevoCliente. <tr class="control" > <td> Fotografía: </td> <td> <s:file name="cliente.foto" </tr> <tr class="control" > <td align="right" > <input type="submit" name="boton01" value="Registrar" > </td> </tr> </table> </s:form> /> </td> 2 Notas: 1) Debe utilizar el atributo enctype del formulario con el valor multipart/form-data. Complete el código con la lógica mostrada a continuación: <s:form action="ingresaCliente" method="post" enctype="multipart/form-data" > 1 <table> <tr class="titulo" > <td colspan="2" align="center" > Registro de Clientes </td> </tr> <tr class="control" > <td> <s:text name="key. .cliente. 2) Agregue la etiqueta file de Struts 2.jsp Dentro de la página nuevoCliente.nombre" /> </td> <td> <s:textfield name="cliente.jsp. .. . es decir. hará referencia a un objeto de nombre cliente que cuente con un atributo llamado foto.foto. cuyo nombre es cliente. CARRERAS PROFESIONALES CIBERTEC .nombre" /> </td> </tr> . De esta manera. . se debe modificar el formulario HTML.

service.DESARROLLO DE APLICACIONES WEB I 33 d) Paso 4: Registrar el alias ingresaCliente en el archivo struts.action. Note que al invocar este alias se ejecutará dentro de la clase ClienteAction el método registrar.List. public class ClienteAction { // creamos un atributo de tipo Lista de Clientes ClienteDTO cliente. import aprendamos.java. CIBERTEC CARRERAS PROFESIONALES .xml <action name="ingresaCliente" class="aprendamos.jsp. List<ClienteDTO> clientes. import java.java.util.jsp</result> 1 Notas: 1) El alias ingresaCliente fue definido en el formulario de la página nuevoCliente.PaqueteBusinessDelegate.ClienteService_I.ClienteDTO.service.action. import aprendamos.java.java..bean. import aprendamos.ClienteAction" method="registra" > <result name="exito" </action> >/listado.java.. e) Paso 5: Crear el método registrar en la clase ClienteAction La clase ClienteAction debe contar con la siguiente lógica: package aprendamos. 1 .

try { servicioCliente. el Framework instancia el objeto y almacena en él los datos que llegan desde la página nuevoCliente. listaClientesPorNombre(cliente..getClienteService(). 2) El objeto servicioCliente es un componente de la lógica de negocio y expone las operaciones que puede realizar la clase ClienteAction.printStackTrace(). 2 // creamos el metodo registra public String registra(){ String vista="exito".jsp todos los campos llevan como prefijo en el nombre la palabra cliente. Note que en la página nuevoCliente.jsp. la cual hace referencia a la variable definida en ClienteAction.jsp 4) Una vez registrado el nuevo cliente se “blanquea” el atributo nombre del objeto cliente y se invoca la funcionalidad de listado antes de retornar a la vista respectiva. deben existir los campos necesarios para poder gestionar la imagen del cliente seleccionada en la página nuevoCliente. } catch (Exception e) { // TODO Auto-generated catch block e.. ClienteService_I servicioCliente = PaqueteBusinessDelegate. De manera automática.34 .getNombre()). } 3 4 Notas: 1) Se ha definido la variable cliente de tipo ClienteDTO.registraElCliente(cliente). clientes= servicioCliente. 3) Note que el método registraCliente recibe como parámetro el objeto cliente. // lo retornado por el servicio lo asignamos al atributo de tipo Lista de clientes cliente. Dentro de él.setNombre(""). CARRERAS PROFESIONALES CIBERTEC . } return vista.

por requerimiento del Framework. Ambos se “cargarán” de manera automática y proporcionarán importante información relacionada con la variable foto. también.fotoContentType = fotoContentType. private String fotoFileName. . definir los campos fotoContentType y fotoFileName.foto. se define la variable isFoto de tipo InputStream. private private private private private private String nombre. String usuario. } . es necesario definirlo en la clase ClienteDTO.jsp se ha definido un campo tipo file con el nombre cliente. de modo que se pueda recepcionar la imagen enviada desde el formulario. double sueldo. CIBERTEC CARRERAS PROFESIONALES . Notas: 1) Dado que en la página nuevoCliente.DESARROLLO DE APLICACIONES WEB I 35 f) Paso 6: Modificar la clase ClienteDTO La clase ClienteDTO debe contar con la siguiente lógica: public class ClienteDTO implements Serializable { private static final long serialVersionUID = 1L. 1 2 private File foto. String clave. String sexo. 2) Es necesario. . debido a que ésta será utilizada por el componente MySqlClienteDAO en el registro de la imagen en la tabla tbcliente. private InputStream isFoto. Date fecnac. private String fotoContentType. } public void setFotoContentType(String fotoContentType) { this. public String getFotoContentType() { return fotoContentType. Adicionalmente.

CARRERAS PROFESIONALES CIBERTEC . La clase ClienteService implementa la interface ClienteService_I. el atributo foto debe ser diferente del valor null.registraCliente(objCliente).getFoto()!=null){ InputStream tempo = new FileInputStream(objCliente. } 1 Notas: 1) Si el cliente seleccionó en la página nuevoCliente. De ser el caso. se asigna el objeto tempo al atributo isFoto (utilizado en la clase MySqlClienteDAO para grabar la imagen en la tabla tbcliente).getFoto()).jsp una imagen.36 g) Paso 7: Modificar la clase ClienteService La clase ClienteService debe contar con la siguiente lógica en el método registraElCliente: public int registraElCliente(ClienteDTO objCliente) throws Exception { // aqui agremos un poco de logica // como sabemos que el atributo isFoto esta llegando nulo // lo generamos a partir del atributo foto (de tipo File) if(objCliente. Luego.setIsFoto(tempo). se crea un objeto temporal de tipo InputStream en base al atributo foto. objCliente. } return objClienteDAO. Recuerde que el método registraElCliente debe ser “expuesto” registrándolo en la interface ClienteService_I.

Date al tipo java. objCliente. pst. Connection cn = MySqlDBConn.util.Date. // asignamos valores a las interrogantes pst.?)".executeUpdate().?. objCliente.sueldo.setDouble(2.setBinaryStream(7.setBinaryStream(7. bdfecha).setString(1.sql.close(). cn.getSueldo()).0). PreparedStatement pst = cn. String sql = "insert into tbcliente(nombre.obtenerConexion().getClave()).sexo.getTime()).getIsFoto().prepareStatement(sql). objCliente.getFoto()!=null){ pst.getNombre()). // no olvidemos insertar la fecha :) java." + "usuario. se asume que no insertará ninguna imagen en el campo foto: CIBERTEC CARRERAS PROFESIONALES .sql.Date bdfecha= new java. objCliente. if(objCliente.setString(3.?. pst.available()). pst.getSexo()).setString(6.?. return resultado. objCliente.DESARROLLO DE APLICACIONES WEB I 37 h) Paso 8: Modificar la clase MySqlClienteDAO La clase MySqlClienteDAO debe implementar la siguiente lógica en el método registraCliente: public int registraCliente(ClienteDTO objCliente) throws Exception{ int resultado =0.getIsFoto(). objCliente. pst.fecnac. } Notas: 1) Recuerde que para insertar una fecha en base de datos debe convertir las fechas de tipo java.?. 2) Por defecto. null.foto) values (?.sql.clave. objCliente.?.setString(5.getFecnac(). } 1 2 // ejecutamos la sentencia resultado = pst.setDate(4.getUsuario()). pst.Date(objCliente. pst.

objCliente.0). se envía como tercer parámetro del método setBinaryStream(). CARRERAS PROFESIONALES CIBERTEC . De esta manera. El método available() de un objeto de tipo InputStream retorna la cantidad de bytes (el tamaño). si el valor del atributo es diferente de null. registra la imagen.38 pst. de la imagen a insertar en la tabla.getIsFoto(). tomando como base al atributo de tipo InputStream isFoto: pst.setBinaryStream(7. en este caso. null. Sin embargo. objCliente.available()).setBinaryStream(7.getIsFoto().

DESARROLLO DE APLICACIONES WEB I 39 i) Paso 9: Ejecutar la aplicación web Seleccione del listado de Clientes el enlace Nuevo Cliente: CIBERTEC CARRERAS PROFESIONALES .

CARRERAS PROFESIONALES CIBERTEC . ingrese los campos solicitados.40 En la pantalla mostrada.

se grabará un nuevo registro en la base de datos y se visualizará nuevamente el listado de Clientes. CIBERTEC CARRERAS PROFESIONALES .DESARROLLO DE APLICACIONES WEB I 41 Al hacer clic sobre el botón Registrar.

j) Paso 10: ¡Bien!. CARRERAS PROFESIONALES CIBERTEC . ha culminado la funcionalidad “registra imagen” exitosamente. utilizando la herramienta MySql Query Browser: 1 Notas: 1) Al hacer clic sobre la lupa. visualizará en una nueva ventana la imagen registrada en la tabla tbcliente.42 Se puede verificar el correcto registro de la imagen.

• La aplicación puede ser fácilmente adaptada a nuevos lenguajes y regiones. todo el trabajo para soportar nuevos lenguajes o naciones. es probable. pero no necesariamente) que comparte personalizaciones. Una clase locale es una región (usualmente geográfica. cultura y lenguaje. alguna vez. Cuando se internacionaliza una aplicación. Para aplicaciones donde el soporte I18N no ha sido planeado o incorporado. la cual ha sido internacionalizada apropiadamente con la específica. los desarrolladores de software se centran en construir aplicaciones que resuelvan en forma inmediata problemas de negocio. ésta será una experiencia desagradable para el usuario. En muchos casos. aquí es donde los beneficios de I18N en la plataforma java se ejecutan.1. imágenes y mensajes que son incluidos dentro CIBERTEC CARRERAS PROFESIONALES . Se deben crear versiones localizadas de la aplicación para cada lenguaje específico y región que debe soportar. esto usualmente significa cambios de texto. estas asunciones son válidas y no hay preguntas sobre quién será la audiencia. • Dependencia culturales de datos. Localización (L10N) es el proceso de adaptar su aplicación. no se puede producirla para elegir qué opciones desea soportar. Si un usuario visita un sitio web y todos sus textos. son externas al código fuente. porque estas asunciones fueron incorrectas. Para aplicaciones que están siendo apropiadamente internacionalizadas. • Los elementos de texto. Una aplicación que dice tener soporte para internacionalización debe contar con las siguientes características: • Puede soportar lenguajes adicionales sin requerir cambios adicionales de código. tales como fecha y hora. no será necesario rediseñar nuestras aplicaciones cada vez que se necesite soporte para un nuevo lenguaje. Se deben implementar todas ellas o el proceso colapsará. imágenes y botones están en el lenguaje correcto.DESARROLLO DE APLICACIONES WEB I 43 1.4. Internacionalización – I18n Tradicionalmente. Mientras hacen eso es fácil y a veces necesario realizar asunciones acerca del lenguaje o lugar de residencia de los usuarios. y valores decimales son correctamente formateados para el lenguaje del usuario y localización geográfica. Dada esta característica. Afortunadamente. Internacionalización (I18N) es el proceso de diseñar su software con soporte en tiempo real de múltiples lenguajes y regiones. Aplicaciones que son escritas para una sola localización son comúnmente referenciadas como miopes. mensajes e imágenes son almacenados externamente al código fuente. que se deba reconstruir una aplicación. pero los números y fechas no son formateados correctamente. Asegurar que una aplicación puede soportar múltiples lenguajes y regiones solo es el primer paso. Sin embargo. • Caracteres no estándares son soportados.

1. dentro del proyecto. Se debe iniciar planificando. De acuerdo con Richard Gillam. el soporte para I18N en las aplicaciones.1. a) Paso 1: Importar el proyecto FuncionalidadRegistraImagenI18N_Inicial. Ejercicio 1: Funcionalidad Registra imagen con i18N Se agregará nueva funcionalidad al registro de imágenes implementado. cuenta con el paquete aprendamos. miembro del Grupo de Tecnología Unicote (autor del diseño de muchas de las librerías Java para soporte I18N). La aplicación web soportará el uso de tres idiomas distintos.java.44 del código fuente. Después de los cambios aplicados.recursos y dentro de él cuenta con tres archivos de recursos (archivos . Imagine hacer eso cada vez para una nueva localización soportada.4.1. en forma temprana.war web 1 Notas: 1) Note que. los usuarios esperarán que los productos que utilizan trabajen para ellos en su lenguaje nativo. éste debe de ser recopilado. Se pueden obtener experiencias negativas si los usuarios no están satisfechos cuando las asunciones que se realizan son incorrectas.properties) que soportan los CARRERAS PROFESIONALES CIBERTEC .

El primero está configurado en el archivo sin indicador de idioma.DESARROLLO DE APLICACIONES WEB I 45 idiomas italiano (it).bienvenida = Ir à página inicial menu. b) Paso 2: Editar los archivos .jsp.properties. Defina las keys para el idioma portugués en el archivo MisRecursos_pt. las keys que serán utilizadas en la página bienvenida. seus dados são: #keys para el menu menu. Se crearán.listado = Ir para a lista CIBERTEC CARRERAS PROFESIONALES .saludo = Bem-vindo Caro usuário. Note que los prefijos it y pt o cualquier otro que se desea usar deben ser códigos ISO 639-1.logueo = Vá para a entrada menu.properties #keys para la pagina de bienvenida key.nombre = Nome: key. portugués (pt) y español.usuario = Usuário: key.sexo = sexo: key.fecnac = data de nascimento: key. como ejemplos.

saludo= Bienvenido estimado usuario.nombre = Nombre: key.logueo = Ir al logueo menu.properties (archivo de recursos por defecto).bienvenida = Vai alla pagina di benvenuto menu.nombre = Nome: key. i dati sono: #keys para el menu menu.sexo = sesso: key.listado = Ir al listado CARRERAS PROFESIONALES CIBERTEC .46 Defina las keys para el idioma italiano en el archivo MisRecursos_it.fecnac = Data di Nascito: key.bienvenida = Ir a la página de Bienvenida menu.fecnac = Fecha de Nacimiento: key.sexo = Sexo: key.usuario = Usuario: key.listado = Ir al listadini Defina las keys para el idioma español en el archivo MisRecursos.properties #keys para la pagina de bienvenida key.logueo = Ir al logueini menu. sus datos son: #keys para el menu menu.usuario = Utente: key. 1 #keys para la pagina de bienvenida key.saludo = Benvenuto Caro utente.

c) Paso 3: Modificar el archivo cabecera. se configura sul valor como el idioma actual de la aplicación web.contextPath}/a_bienvenida?request_loc ale=it"> <img src="imagenes/banderaItalia.png" alt="Portugues" border="0"> </a> 2 </td> <td><a href="${pageContext. automáticamente.request.contextPath}/a_bienvenida?request_loc ale=pt"> <img src="imagenes/BanderaBrasil. en CIBERTEC CARRERAS PROFESIONALES .contextPath}/a_bienvenida?request_loc ale=es"> <img src="imagenes/banderaPeru. En el ejemplo. Cuando se seleccione en la aplicación web un idioma que no haya sido configurado en ningún archivo de recursos.png" border="0" > <table> <tr><td> <a href="${pageContext.jsp <body class="titulo" > <img alt="" src="imagenes/logo. struts 2 recupera las keys del archivo de recursos por defecto. de manera automática.DESARROLLO DE APLICACIONES WEB I 47 Notas: 1) El archivo de recursos por defecto es aquel que no tiene código ISO asociado a un idioma en particular. Cuando se utiliza éste.png" alt="Italiana" border="0"> </a> </td> <td><a href="${pageContext.request. 2) Es recomendable utilizar variables al referenciar cualquier recurso dentro de una aplicación web.request.png" alt="Español" border="0"> </a> </td> </tr> </table> </body> 1 Notas: 1) Struts 2 soporta cuenta con un parámetro especial llamado request_locale.

48 lugar de colocar el nombre de la aplicación web. CARRERAS PROFESIONALES CIBERTEC .jsp </result> </action> <action name="a_logueo" > <result > /logueo. . . .xml .request.jsp.jsp </action> . . <package name="default" namespace="/" extends="strutsdefault"> 1 <action name="a_bienvenida" > <result > /bienvenida. e) Paso 5: Recuperar las keys del menú y de la página de bienvenida. Notas: 1 </result> 1) Note que el action a_bienvenida es solo un action de atajo que invoca automáticamente a la página bienvenida. se realiza lo siguiente: FuncionalidadRegistraImagenI18N_Inicial Se coloca un “expression language” equivalente: ${pageContext. Se puede crear dentro de la aplicación múltiples actions de atajo para invocar a través de links a las páginas JSP.contextPath} d) Paso 4: Registrar el action a_bienvenida en el archivo struts. utilizando la etiqueta <s:text> de struts 2.

.jsp . utilizando la siguiente directiva: <%@ taglib prefix="s" uri="/struts-tags" %> CIBERTEC CARRERAS PROFESIONALES . Es importante recordar que para utilizar las etiquetas de struts 2 se debe referenciar la librería.DESARROLLO DE APLICACIONES WEB I 49 Modifique el archivo menu. .logueo" /> </s:a> </td> </tr> <tr> <td class="control" > <s:a action="a_listado" > <s:text name="menu.listado" /> </s:a> </td> </tr> .bienvenida" /> </s:a> </td> </tr> <tr> <td class="control" > <s:a action="a_logueo" 1 > <s:text name="menu. Notas: 1) Debe usar la etiqueta <s:text> para referenciar a las keys del archivo de recursos. . . <tr> <td class="control" > <s:a action="a_bienvenida" > 1 <s:text name="menu.

.nombre" /> </td> <td>${sessionScope.saludo" /> </td> </tr> <!-recuperamos los atributos del usuario logueado utilizando EL (Expression Language) --> 1 <tr> <td><s:text name="key. <table class="control" > <tr> <td colspan="2" > <s:text name="key. . .fecnac}</td> </tr> <tr> <td> <s:text name="key.sexo}</td> </tr> </table> .usuario}</td> </tr> <tr> <td> <s:text name="key.b_usuario.sexo" /> </td> <td>${sessionScope.50 Modifique el archivo bienvenida.b_usuario.b_usuario.usuario" /> </td> <td>${sessionScope.b_usuario.nombre}</td> </tr> <tr> <td> <s:text name="key. .fecnac" /> </td> <td>${sessionScope. CARRERAS PROFESIONALES CIBERTEC .jsp .

Seleccione la bandera italiana. CIBERTEC CARRERAS PROFESIONALES . Se debe visualizar la pantalla de bienvenida y los enlaces a los idiomas definidos en la página cabecera.jsp.DESARROLLO DE APLICACIONES WEB I 51 f) Paso 6: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo.

seleccione la bandera del Perú. Seleccione la bandera de Brasil. Se visualizará la siguiente pantalla con el menú y la bienvenida en idioma portugués. CARRERAS PROFESIONALES CIBERTEC . Finalmente.52 Visualizará la siguiente pantalla con el menú y la bienvenida en idioma italiano.

g) Paso 7: ¡Bien!. ha culminado la funcionalidad “registra imagen con I18n” exitosamente.DESARROLLO DE APLICACIONES WEB I 53 Se visualizará la siguiente pantalla con el menú y la bienvenida en idioma castellano. CIBERTEC CARRERAS PROFESIONALES .

1. Se tendrá un conjunto de “n” conexiones para asignarlas (o prestarlas) a los hilos que lo requieran. a) Paso 1: Importar el proyecto FuncionalidadRegistraImagenPool_Inicial.war web CARRERAS PROFESIONALES CIBERTEC .2. En el caso de las aplicaciones abiertas en Internet o con gran cantidad de usuarios potenciales. El recurso es la conexión a la base de datos.1.2 Acceso optimizado a base de datos y otras características Struts 2 1. el análisis es el mismo. Ejercicio 1: Funcionalidad Registra Imagen “Pool” Se implementa la funcionalidad indicada haciendo uso de un pool de conexiones de MySql para optimizar el acceso a base de datos. Lo recomendable al usar un Pool de Conexiones es que se optimice las consultas a la base de datos para tener mayor rapidez. Uso de un Pool de conexiones para acceso a base de datos Un Pool de Conexiones (jdbc) es un conjunto de conexiones preinstanciadas que serán "prestadas" a los threads (hilos) de ejecución a medida que estos lo requieran para que la usen y luego la devuelvan al pool.54 1.2.1.1.

xml. dentro del proyecto. CIBERTEC CARRERAS PROFESIONALES .DESARROLLO DE APLICACIONES WEB I 55 1 Notas: 1) Observe que. cuenta en la carpeta META-INF con el archivo context. En él. se debe crear la configuración del pool de conexiones que utilizará para acceder a una base de datos.

10000.Este es un comentario --> <!-. En este ejemplo. se tendrá la necesidad de incrementar o redecir este valor por defecto. como máximo. Esta zona de memoria estara "viva" mientras no reiniciemos la aplicacion web --> <Context path="/jee-web" > <!-.0" encoding="UTF-8"?> <!-.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="root" password="" driverClassName="com. 3) El máximo tiempo de espera. 10 segundos para obtener una conexión disponible (de las 100 existentes). De no conseguirla.xml y configurar el pool de conexiones.jdbc. se produciría un error. <?xml version="1. En algunos casos. En este caso un pool de conexiones --> <Resource name="jdbc/sisepuede" auth="Container" type="javax. Este valor debe ser calculado para cada aplicación web sobre la base de la “experiencia” y el tráfico que normalmente se soporte.Driver" url="jdbc:mysql://localhost:3306/facilito"/> 1 2 3 </Context> Notas: 1) jdbc/sisepuede es el nombre del pool de conexiones que utilizará para referenciar a la base de datos. se esperará.56 b) Paso 2: Editar el archivo context. CARRERAS PROFESIONALES CIBERTEC .registramos un recurso en esta zona de memoria.sql.mysql. 2) El número máximo de conexiones activas es 100 en el ejemplo. está expresado en milisegundos.la etiqueta Context representa una zona de memoria que se crea cuando levantamos la aplicacion web.

DESARROLLO DE APLICACIONES WEB I 57 c) Paso 3: Modificar el archivo MySqlDbConn.*. Ésta representa un pool de conexiones en java.naming.util.naming.* debido a que dentro de él se encuentra la clase DataSource. public class MySqlDBConn { // Utilizaremos mas bien un pool de conexiones // creamos el metodo que nos permite obtener una conexion .*. // Esta clase nos retornara una conexion a base de datos import java.java package aprendamos.sql.*.java. import javax. import javax. . . ya que en él se encuentran las clases para utilizar JNDI y acceder al pool de conexiones. 4) Debe importar el pauete javax.*. 1 2 Notas: 3) Debe importar el paquete javax. CIBERTEC CARRERAS PROFESIONALES .sql.sql.

Para referenciar al pool creamos un contexto JNDI // Java Naming and Directory Interface Connection cn=null. CARRERAS PROFESIONALES CIBERTEC . public static Connection obtenerConexion(){ // 1.58 . // obtenemos a traves de su nombre a nuestro // pool de conexiones DataSource ds= (DataSource)ctx. hemos obtenido la conexion del pool"). Todas las denominaciones de objetos JNDI (como nuestro pool). para ello usamos el // famoso metodo lookup. 2) A través del método lookup y utilizando el nombre raíz del contexto.println( "Mision cumplida. try { // creamos el contexto JNDI Inicial..lookup(raizContexto+"jdbc/sisepuede").out. utiliza la infor de META INF para hacer un pool de conexiones. JNDI maneja nombres y objetos Context ctx = new InitialContext(). 1 2 } catch (NamingException e) { // TODO Auto-generated catch block e. se crean debajo de este nombre raíz.printStackTrace().getConnection(). } return cn. // le pedimos al pool que nos de una conexion cn = ds. para referenciar al pool. Por lo tanto.printStackTrace(). . System. //Base standar JND String raizContexto ="java:comp/env/". JDNI valida los nombres . se pasar primero por el nombre raíz. . se referencia al pool de conexiones: jdbc/sisepuede. } Notas: 1) El nombre del contexto JNDI por default es java:comp/env. // ahora vamos a ubicar un nombre dentro // de este contexto. } catch (SQLException e) { // TODO Auto-generated catch block e.

DESARROLLO DE APLICACIONES WEB I 59 Se obtiene un objeto de tipo DataSource que representa el pool almacenado en memoria. quien solicita al servidor de base de datos las conexiones (en el ejemplo cien). que serán almacenadas en la memoria del servidor y que juntas constituyen el pool de conexiones. CIBERTEC CARRERAS PROFESIONALES . d) Paso 4: Copiar el conector de mysql dentro de la carpeta lib del servidor de aplicaciones TomCat 1 Notas: 1) Este paso es necesario debido a que es el servidor Tomcat y no la aplicación web.

CARRERAS PROFESIONALES CIBERTEC .60 e) Paso 5: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo.

CIBERTEC CARRERAS PROFESIONALES . se visualizará en la consola de Eclipse los mensajes del Logueo y el que se colocó en la clase MySqlDbConn: misión cumplida. También. se ha obtenido la conexión del pool.DESARROLLO DE APLICACIONES WEB I 61 Debe visualizar la pantalla de bienvenida con los datos del usuario logueado.

62 f) Paso 6: ¡Bien!. CARRERAS PROFESIONALES CIBERTEC . ha culminado la funcionalidad “registra imagen pool” exitosamente.

Principales componentes Dentro de la familia de nuevas etiquetas de Struts 2.2.DESARROLLO DE APLICACIONES WEB I 63 1.2. a) Paso 1: Importar el proyecto proyecto web FuncionalidadCargaDatosCliente_Inicial.2. la cual es referenciada en un JSP de la siguiente manera: <%@ taglib prefix="s" uri="/struts-tags" %> Se detalla.war 1 CIBERTEC CARRERAS PROFESIONALES . Ejercicio 2: Funcionalidad carga datos del Cliente Se implementa la funcionalidad indicada haciendo uso de las utilidades incluidas en el Framework para procesar archivos (en el ejemplo la imagen del cliente) a través de un formulario HTML y el uso de un Action de Struts 2 que utiliza un nuevo tipo de Result: stream. a continuación.2. ejercicios de aplicación en los que se utilizan las principales etiquetas de Interface de usuario y datos de Struts 2: <s:url> <s:action> <s:form> 1.1. es importante destacar que. todas las etiquetas básicas del framework se encuentran en una sola librería. Librerías de etiquetas de Struts 2. en esta versión.

64 Notas: 1) Debe modificar la página listado.usuario} </s:param> </s:url> <a </td> href="${carga}" > M </a> 1 . b) Paso 2: Modificar el archivo listado. Complete el código con la lógica mostrada a continuación: . . CARRERAS PROFESIONALES CIBERTEC . debe crear un nuevo enlace para visualizar los datos del cliente seleccionado.jsp Dentro de la página listado.jsp. . <td align="center" > <s:url id="carga" action="cargaModificaCliente" > <s:param name="usuario" > ${elcli.jsp para agregar un enlace que permita visualizar los datos de un cliente en particular. . .

Su valor es asignado usando el siguiente expression language (EL): ${elcli.jsp. tal como se muestra en la pantalla previa. determine el parámetro usuario utilizando la etiqueta <s:param>. Adicionalmente. CIBERTEC CARRERAS PROFESIONALES .usuario} 2) Culminado el cambio en listado.DESARROLLO DE APLICACIONES WEB I 65 2 Notas: 1) Utilizando la etiqueta <s:url > defina un enlace que permitirá invocar al alias cargaModificaCliente. visualizará el enlace.

service.ClienteDTO.action.66 c) Paso 3: Registrar el alias cargaModificaCliente en el archivo struts.java.jsp </result> </action> 1 Notas: 1) El alias cargaModificaCliente fue referenciado en el enlace definido para modificar (M) de la página listado.action.PaqueteBusinessDelegate. import java.java.java.. import aprendamos. public class ClienteAction { // creamos un atributo de tipo Lista de Clientes ClienteDTO cliente.util.ClienteAction" method="cargaModifica" > <result name="exito" >/modificaCliente. import aprendamos.java.bean. import aprendamos. CARRERAS PROFESIONALES CIBERTEC .java.service. d) Paso 4: Crear el método cargaModifica en la clase ClienteAction La clase ClienteAction debe contar con la siguiente lógica: package aprendamos. 1 .jsp. String usuario.. List<ClienteDTO> clientes.ClienteService_I.xml <action name="cargaModificaCliente" class="aprendamos. Note que al invocar este alias se ejecutará dentro de la clase ClienteAction el método cargaModifica.List.

se invocará a la página modificaCliente. } return vista. public String cargaModifica(){ String vista="exito"..buscaClientePorUsuario( this. Notas: 1) Se ha definido la variable usuario de tipo String..getUsuario()). 3) Luego. De manera automática. try { cliente= servicioCliente.DESARROLLO DE APLICACIONES WEB I 67 . el Framework instancia el objeto y almacena en éste el parámetro usuario.jsp. se retorna a la vista respectiva.jsp CIBERTEC CARRERAS PROFESIONALES .printStackTrace(). } 3 . Se definen también los métodos setUsuario() y getUsuario(). que llega desde la página listado. respectivamente.. . 2 } catch (Exception e) { // TODO Auto-generated catch block e. es decir.. 2) Note que el método buscaClientePorUsuario recibe como parámetro la variable usuario y retorna un objeto de tipo ClienteDTO que es asignada a la variable cliente.

68 e) Paso 5: Verificar la clase MySqlClienteDAO La clase MySqlClienteDAO debe implementar la siguiente lógica en el método buscaPorUsuario: public ClienteDTO buscaPorUsuario(String usuario) throws Exception{ ClienteDTO objClienteDTO=null. Este atributo es de tipo InputStream. objClienteDTO.setSexo(rs.setIsFoto(rs. //asignamos valores a las interrogantes pst.getString(5)).sexo. por ello. objClienteDTO.setFecnac(rs. //definimos la sentencia String sql="select usuario.getString(1)).getBinaryStream(7)).sueldo. 1 2 //ejecutamos ResultSet rs=pst. objClienteDTO.getDate(6)).getDouble(4)).setClave(rs.getBinaryStream(7) CARRERAS PROFESIONALES CIBERTEC .setSueldo(rs. } Notas: 1) Note que se obtiene el campo de tipo longblob foto.fecnac. //si hay datos. objClienteDTO.executeQuery(). 2) El campo foto es asignado al atributo isFoto del objeto objClienteDTO.foto " + " " + "from tbcliente where usuario = ?".setString(1.usuario).getString(2)).obtenerConexion().prepareStatement(sql). objClienteDTO. debe ser recuperado con el método getBinaryStream del objeto ResultSet rs: rs. return objClienteDTO.next()){ objClienteDTO = new ClienteDTO().getString(3)).close(). } cn. Connection cn = MySqlDBConn. objClienteDTO.setNombre(rs.setUsuario(rs.nombre. recuperamos un regsitro if(rs.clave. //la preparamos PreparedStatement pst=cn. objClienteDTO.

CIBERTEC CARRERAS PROFESIONALES . modificarlos.DESARROLLO DE APLICACIONES WEB I 69 f) Paso 6: Ejecutar la aplicación web Seleccione del listado de Clientes el enlace M asociado a cualquiera de los clientes listados: 1 Notas: 1) Enlace para visualizar los datos del cliente y. opcionalmente.

ha culminado la primera parte de la funcionalidad “carga imagen” CARRERAS PROFESIONALES CIBERTEC . no reconoce aún la fotografía. g) Paso 7: ¡Bien!.70 En la pantalla mostrada. Sin embargo. se visualizarán los datos asociados al cliente seleccionado.

.usuario}" /> </td> </tr> . .jsp debe utilizar la etiqueta HTML <img> para visualizar la fotografía asociada al cliente mostrado: . . Se envía adicionalmente el parámetro usuario con el valor ${cliente.usuario}.DESARROLLO DE APLICACIONES WEB I 71 h) Paso 8: Modificar la página modificaCliente. CIBERTEC CARRERAS PROFESIONALES . Notas: 1) Note cómo en el atributo src de la etiqueta <img> se hace referencia al alias cargaImagenCliente.foto" /> <td> <img alt="Fotografia del Cliente:) " </td> 1 src="cargaImagenCliente?usuario=${cliente.jsp Dentro de la página modificaCliente. <tr class="control" > <td> Fotografía: </td> <td> <s:file name="cliente. .

3) El campo imagenClienteRecuperada es el valor asociado al parámetro del result: inputName. CARRERAS PROFESIONALES CIBERTEC .action.xml <action name="cargaImagenCliente" class="aprendamos.jsp visualizará la imagen a partir de un campo de tipo InputStream.en inputName colocamos el nombre del atributo del action que permitira generar el flujo (stream) --> <param name="inputName">imagenClienteRecuperada</param> </result> </action> 1 2 3 Notas: 1) El alias cargaImagenCliente fue referenciado en la etiqueta <img> de la página modificaCliente.jsp. Note que al invocarlo se ejecutará dentro de la clase ImagenAction el método recuperaImagenCliente. A través de él. 2) Se utiliza un nuevo tipo de result: stream.72 i) Paso 9: Registrar el alias cargaImagenCliente en el archivo struts.ImagenAction" method="recuperaImagenCliente" > <result name="exito" type="stream" > <!-. la etiqueta <img> de la página modificaCliente. Éste debe ser de tipo InputStream y estar definido en el action ImagenAction.java.

import aprendamos.PaqueteBusinessDelegate. import java. try { ClienteDTO cli= servicioCliente.service.ClienteService_I. InputStream imagenClienteRecuperada. CIBERTEC CARRERAS PROFESIONALES . public String recuperaImagenCliente(){ String vista="exito". } 2 3 ..bean.DESARROLLO DE APLICACIONES WEB I 73 j) Paso 10: Crear el método recuperaImagenCliente en la clase ImagenAction La clase ImagenAction debe contar con la siguiente lógica: package aprendamos. public class ImagenAction { String usuario. 1 .java.. import aprendamos.getIsFoto().. import aprendamos.action.java. } return vista.ClienteDTO..java. .io.imagenClienteRecuperada = cli.java..buscaClientePorUsuario(usuario). } catch (Exception e) { // TODO Auto-generated catch block e.*.service. // del objeto cli solo nos importa la foto como InputStream // recuperamos ese atributo y lo asignamos al campo // imagenClienteRecuperada this.printStackTrace()..

en el registro del action ImagenAction.74 Notas: 1) Se ha definido la variable imagenClienteRecuperada de tipo InputStream. k) Paso 11: Ejecutar la aplicación web Seleccione. 3) Se invoca el método getIsFoto() de la variable cli para obtener la imagen recuperada de base de datos y asignarla a la imagenClienteRecuperada. CARRERAS PROFESIONALES CIBERTEC . del listado de Clientes el enlace M asociado a cualquiera de los clientes listados: 1 Notas: 1) Enlace para visualizar los datos del cliente y. opcionalmente. modificarlos. nuevamente.xml. 2) El método buscaClientePorUsuario retorna un objeto de tipo ClienteDTO que es asignado a la variable cli. Ésta es referenciada en el archivo struts.

l) Paso 12: ¡Muy Bien!. sí visualizará la fotografía asociada al cliente. ha culminado exitosamente la funcionalidad completa “carga imagen”.DESARROLLO DE APLICACIONES WEB I 75 En la pantalla mostrada. se visualizarán los datos asociados al cliente seleccionado. CIBERTEC CARRERAS PROFESIONALES . En esta oportunidad.

la tecnología JSP no proporciona ningún soporte directo para diseños o gestores de diseño. éste puede sufrir muchos cambios durante su ciclo de vida. de esta manera. la configuración y uso de la librería Tiles. Para ello. Ésta es de código abierto e implementa el patrón Composite View.1. se harán las modificaciones necesarias para implementar el patrón Composite View. a través de un ejercicio.2. a continuación. Se muestra. Utilizar diseños y gestores de diseño puede ayudar a organizar las diferentes partes de un JSP de modo que éstos se puedan alterar con un mínimo impacto para el resto de la aplicación.2.3. es por ello que surgen librerías en el mercado que pueden ser utilizadas para mejorar la estructura de nuestras aplicaciones web. 1.3. Desafortunadamente. el patrón de diseño Composite View. de manera eficiente y escalable. Patrón Composite View – Struts 2 Tiles Al momento de crear el diseño de un sitio web típico. gestionar diversos diseños para un sitio web. Ejercicio 1: Mantenimiento Completo con Tiles Sobre un mantenimiento completo e implementado con Struts 2. Surge.76 1. CARRERAS PROFESIONALES CIBERTEC . el cual permite. se utilizará el framework Tiles y se integrará a la aplicación web construida sobre Struts 2.

DESARROLLO DE APLICACIONES WEB I

77

a) Paso 1: Importar el proyecto web MantenimientoTiles_Inicial.war

1

2

3

4

Notas: 1) En general, las páginas JSP de la aplicación se encontrarán dentro de carpetas específicas. En este ejemplo, se cuenta con dos tipos: • Páginas. Para todas aquellas de la aplicación web.

CIBERTEC

CARRERAS PROFESIONALES

78

Plantillas. Para las diferentes plantillas tiles sobre las cuales se distribuirán las páginas de la aplicación web.

2) Para utilizar Tiles e integrarlo a struts 2, es necesario contar con las librerías de Tiles y el plug in de Struts 2 para ésta. 3) El archivo de configuración de tiles es tiles.xml y debe copiarse por defecto en la carpeta WEB-INF de la aplicación web. 4) No todos los archivos JSP deben, necesariamente, estar dentro de una carpeta. En el ejemplo, la página logueo.jsp mantiene su ubicación original: dentro de la carpeta WebContent.

b) Paso 2: Modificar el archivo web.xml Se deben agregar en el archivo web.xml las siguientes etiquetas:

<!-- registramos e l listener de strtus 2 titles --> <listener> <listener-class> org.apache.struts2.tiles.StrutsTilesListener </listener-class> </listener> ...

1

Notas: 1) Debe agregar el listener de Tiles para struts 2.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

79

c) Paso 3: Modificar el archivo struts.xml

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd"> <tiles-definitions> <definition name="d_bienvenida" template="/plantillas/diseno01.jsp"> <put-attribute <put-attribute <put-attribute <put-attribute
1 name="menu" value="/paginas/menu.jsp" /> name="pie" value="/paginas/pie.jsp" /> name="cabecera" value="/paginas/cabecera.jsp" /> name="body" value="/paginas/bienvenida.jsp" />

</definition> <definition name="d_listado" extends="d_bienvenida"> <put-attribute name="body" value="/paginas/listado.jsp" /> </definition> <definition name="d_nuevoCliente" extends="d_bienvenida"> <put-attribute name="body" value="/paginas/nuevoCliente.jsp" /> </definition> ...
3 2

Notas: 1) Debe crear definiciones de Tiles. Ésta determina qué componentes (JSPs normalmente) se despliegan sobre una plantilla en particular. En el ejemplo, el definition d_bienvenida referencia a la plantilla diseno01.jsp, 2) Un definition puede ser heredado. De esta manera, solo es necesario “sobre escribir” los puts que queramos modificar. En el ejemplo, el definition d_listado hereda del definition d_bienvenida. 3) Note que los puts dentro de los definitions están referenciando a páginas JSP dentro de la carpeta páginas. Ésta debe existir y ahí deben encontrarse las páginas referenciadas.

CIBERTEC

CARRERAS PROFESIONALES

devMode" value="false" /> <package name="default" namespace="/" extends="tiles-default"> <!-.DynamicMethodInvocation" value="false" /> <constant name="struts.registramos nuestro primer action --> <action name="logueo" class="aprendamos.LogueoAction" > <result name="error" >/logueo. más bien. 2) Cada <result> de un action.xml .. es obligatorio heredar del paquete tiles-default..jsp </result> <result name="exito" type="tiles"> d_bienvenida </action> . a un definition de tiles. <struts> <constant name="struts. </result> Notas: 1) Para trabajar con Tiles y struts 2. sino. CARRERAS PROFESIONALES CIBERTEC ..enable. ya no invoca directamente a una página JSP.80 d) Paso 4: Modificar el archivo struts.java.creamos un action de atajo --> <action name="a_nuevoCliente" > <result type="tiles"> d_nuevoCliente </action> <action name="a_bienvenida" > <result type="tiles"> d_bienvenida </action> <action name="a_logueo" > <result > /logueo.action.jsp </action> 1 </result> 2 </result> 3 </result> <action name="a_listado" > <result type="tiles"> d_listado </action> </result> <!-. 3) Para que un <result> pueda invocar a un definition de tiles es necesario indicar en su atributo type el valor tiles..

es decir.DESARROLLO DE APLICACIONES WEB I 81 e) Paso 5: Crear el archivo diseno01. dentro de una carpeta llada plantillas.jsp 1 Notas: 1) El archivo debe ser creado tal como se referenció en el archivo tiles. CIBERTEC CARRERAS PROFESIONALES .xml.

charset=ISO-88591"> <title>Insert title here</title> </head> <body> <!-. 2 Notas: 1) Para poder utilizar las etiquetas de tiles dentro de la página JSP. 2) Note cómo se ha creado una tabla con filas y columnas.dtd"> 1 <html> <head> <meta http-equiv="Content-Type" content="text/html.01 Transitional//EN" "http://www.xml.w3. charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="tiles" uri="http://tiles. haciendo uso de la etiqueta <tiles:insertAttribute>.org/tags-tiles"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4. es necesario referenciar a la librería de etiquetas tags-tiles. dentro de las cuales...org/TR/html4/loose. CARRERAS PROFESIONALES CIBERTEC . se insertan los diferentes puts definidos en el archivo tiles.jsp <%@ page language="java" contentType="text/html.en esta plantilla definimos el orden de distribucion de los puts del definition --> <table> <tr> <td colspan="2"><tiles:insertAttribute name="cabecera" /></td> </tr> <tr> <td><tiles:insertAttribute name="menu" /></td> <td><tiles:insertAttribute name="body" /></td> </tr> <tr> <td colspan="2"><tiles:insertAttribute name="pie" /></td> </tr> </table> </body> .82 f) Paso 6: Modificar el archivo diseno01.apache.

DESARROLLO DE APLICACIONES WEB I 83 g) Paso 7: Copiar las páginas JSP dentro de la carpeta páginas 1 Notas: 1) Tal como se indicó en el archivo tiles. las páginas JSP deben estar dentro de una carpeta denominada páginas.xml. CIBERTEC CARRERAS PROFESIONALES .

. se duplicaría la implementación del patrón de diseño Composite View.jsp" </td> </tr> <tr> /> 1 <td > <!-.jsp" </td> <!-. ya no es necesario tener directivas include dentro de los JSPs.84 h) Paso 8: Eliminar las directivas <include> de todas las páginas JSP. /> Notas: 1) Dado que ahora se trabajará con Tiles.aqui va la cabecera --> <jsp:include page="cabecera.. Importante: De dejarlas. <table> <tr> <td colspan="2" align="center" > <!-.aqui va el cuerpo --> <td > . CARRERAS PROFESIONALES CIBERTEC .aqui va el menu --> <jsp:include page="menu.

DESARROLLO DE APLICACIONES WEB I 85 i) Paso 9: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo. CIBERTEC CARRERAS PROFESIONALES .

la funcionalidad CARRERAS PROFESIONALES CIBERTEC .86 Visualizará la pantalla de bienvenida de la aplicación j) Paso 10: ¡Bien!. ha culminado “Mantenimiento con Tiles” exitosamente.

org/1. permite tener mayor flexibilidad al momento de una posible migración. Si desea saber más acerca de estos temas.apache. cambiar de una estructura de aplicación a otra.html Aquí encontrará importante documentación oficial y ejemplos de uso del framework Struts 2 http://struts. se puede.DESARROLLO DE APLICACIONES WEB I 87 Resumen Las etiquetas de struts 2 se encuentran agrupadas dentro de una sola librería: <%@ taglib prefix="s" uri="/struts-tags" %> Las etiquetas de struts 2 son parte de la capa de presentación dentro de una arquitectura MVC. encontrará referencias para utilizar Tiles independientemente de Struts: Tiles 2.org/2. únicamente de plantillas. puede consultar las siguientes páginas: http://struts. fácilmente.x/index. A través de éste.x/struts-tiles/ Aquí encontrará documentación oficial sobre el uso de plantillas Tiles dentro de una aplicación implementada con el framework Struts.apache. CIBERTEC CARRERAS PROFESIONALES . También. Con Tiles.

88 CARRERAS PROFESIONALES CIBERTEC .

utilizando las principales características del framework MVC Struts 2 y el framework IBATIS.1.1. implementan la capa de persistencia de datos y la integran con el framework Struts 2. utilizando el frameworks IBATIS. : IBATIS – Introducción : Operaciones básicas de acceso a base de datos con IBATIS 2.2. los alumnos. TEMARIO 2.2.2 Tema 4 : Otras operaciones con IBATIS 2.1.2. 2. CIBERTEC CARRERAS PROFESIONALES . : Otras operaciones y características de IBATIS : Tópicos avanzados de IBATIS e Integración con Struts 2 ACTIVIDADES PROPUESTAS • Los alumnos implementan una aplicación web básica.1 Tema 3 : Introducción a IBATIS 2.2. 2.1.DESARROLLO DE APLICACIONES WEB I 89 UNIDAD DE APRENDIZAJE 2 PERSISTENCIA DE DATOS – FRAMEWORK IBATIS LOGRO DE LA UNIDAD DE APRENDIZAJE • Al finalizar la unidad.

NET (también existe un port para Ruby on Rails llamado RBatis). Ibatis asocia objetos de modelo (JavaBeans) con sentencias SQL o procedimientos almacenados mediante archivos XML. se utiliza JDBC. ocupándose de la gestión de los datos mediante un API.Introducción Ibatis es un framework (marco de trabajo) de código abierto basado en capas desarrollado por Apache Software Foundation. mediante el patrón Data Access Object (DAO) y. Es posible subdividir la capa de persistencia en tres subcapas: • La capa de abstracción será la interfaz con la de la lógica de negocio. tanto con las malas implementaciones de los modelos de datos como con los modelos de objetos. Puede ser implementado en Java y . CARRERAS PROFESIONALES CIBERTEC . • Data Access Object es una abstracción que oculta la persistencia de objetos en la aplicación y proporciona un API de acceso a datos al resto.NET y bases de datos relacionales. • La capa de framework de persistencia será el interfaz con el gestor de Base de Datos. IBATIS . haciendo las veces de fachada (Patrón Facade) entre la aplicación y la persistencia.90 2.jar). Normalmente. El marco de trabajo SQL Maps es muy tolerante. Dentro de sus principales características se destacan: A. que se ocupa de la capa de Persistencia (se sitúa entre la lógica de Negocio y la capa de la Base de Datos).1. se implementa utilizando su framework DAO (ibatis-dao. B. Toda implementación de Ibatis incluye los siguientes componentes: • Data Mapper proporciona una forma sencilla de interacción de datos entre los objetos Java y . utilizando uno específico para la misma. Ibatis utiliza su framework SQL-MAP (ibatis-sqlmap. en Java. simplificando la utilización de bases de datos.1.jar). • La capa de driver se ocupa de la comunicación con la propia base de datos.1 Introducción a IBATIS 2. Se implementa de forma general. particularmente en Ibatis.

a) Paso 1: Importar el archivo FuncionalidadIbatisIntro_Inicial.1. se garantizará un mejor rendimiento y un diseño más claro. etc.war 1 Notas: 1) Observe que debe contar con las librerías básicas de IBATIS para integrar el framework a su aplicación web.1.Introducción Se implementará una aplicación web con los componentes básicos para el correcto funcionamiento del framework IBATIS. CIBERTEC CARRERAS PROFESIONALES . tanto cuando se diseñe la base de datos (normalización apropiada.DESARROLLO DE APLICACIONES WEB I 91 A pesar de ello. 2.) como el modelo de objetos.1. Ejercicio 1: Funcionalidad IBATIS . es muy recomendable que se usen las mejores prácticas. Al hacer esto.

xml es el archivo de configuración por excelencia de IBATIS. En el ejemplo. normalmente se tendrá un SqlMap). (Por cada entidad del modelo de datos. CARRERAS PROFESIONALES CIBERTEC .xml. se muestran dos archivos SqlMaps: Cliente.xml y Producto. por ejemplo. se define. que serán referenciados en la aplicación web.xml. 2) UtilSqlConfig permite tener una representación en java como objeto del archivo SqlMapConfig. el pool de conexiones a utilizar y otros archivos XML (llamados SqlMaps).92 b) Paso 2: Copiar los archivos de configuración y la clase UtilSqlConfig 1 2 Notas: 1) SqlMapConfig. En él.

que contienen las sentencias SQL para operar sobre las entidades que referencian. tener cuidado estos archivos como cualquierr refrerncia de xml de be existir --> <sqlMap resource="aprendamos/java/ibatis/Cliente. se referencia a los archivos XML. que se utilizará para acceder a un origen de datos. 2) A través de la etiqueta <sqlMap>. En el ejemplo.registramos nuestros SqlMaps. se referencian los archivos XML Cliente y Producto..xml <sqlMapConfig> <!-.. el pool se llama: nomerindo. archivo de confiracion por excelncia de IBatis --> <transactionManager type="JDBC"> <dataSource type="JNDI"> <property name="DataSource" value="java:comp/env/nomerindo" /> </dataSource> </transactionManager> <!-. En el ejemplo. Normalmente por cada entidad tendremos un SqlMap. en IBATIS.referenciamos a nuestro pool de conexiones. el pool de conexiones. 2 1 Notas: 1) A través de la etiqueta <transactionManager>.podemos registrar muchos mas sqlmaps --> </sqlMapConfig> .DESARROLLO DE APLICACIONES WEB I 93 c) Paso 3: Modificar el archivo SqlMapConfig. CIBERTEC CARRERAS PROFESIONALES .xml" /> <sqlMap resource="aprendamos/java/ibatis/Producto.xml"/> <!-. se define.

sqlmap.buildSqlMapClient(reader)..SqlMapClientBuilder. } catch (Exception e) { e.ibatis. // Esta clase retorna un objeto que representa el archivo // SqlMapConfig. Este es el principal archivo de // cofiguracion de ibatis //Permite representa sqlMapConfig como un objeto public class UtilSqlConfig { private static final SqlMapClient sqlMap.94 d) Paso 4: Modificar la clase UtilSqlConfig import java. 1 2 CARRERAS PROFESIONALES CIBERTEC . } } public static SqlMapClient getSqlMapInstance() { return sqlMap.sqlmap.ibatis..client.resources.Reader. import com.xml. static { try { String resource = "aprendamos/java/ibatis/SqlMapConfig.getResourceAsReader(resource).io. } } .client. throw new RuntimeException( "Error inicializando la clase UtilSqlConfig class.xml estos es lo que se trata de hacer sqlMap = SqlMapClientBuilder.SqlMapClient.common. import com. import com. Cause: " + e).xml". Reader reader = Resources. //Este objeto presenta al SQLmApConfig.ibatis.Resources.printStackTrace().

se puede utilizar SQL estándar para realizar consultas.. la columna foto es mapeada al atributo laFoto.java. utilizando la sintaxis #value# CIBERTEC CARRERAS PROFESIONALES .lang.com/dtd/sql-map-2. 3 Notas: 1) A través de la etiqueta <typeAlias>.xml <?xml version="1. 3) A través de la etiqueta <select>..ClienteDTO" /> <resultMap class="cli" id="clienteRes" 2 1 > <result <result <result <result <result <result <result </resultMap> property="nombre" column="nombre" /> property="sueldo" column="sueldo" /> property="sexo" column="sexo" /> property="fecnac" column="fecnac" /> property="usuario" column="usuario" /> property="clave" column="clave" /> property="laFoto" column="foto" /> <!-. el dao llamara a las operaciones por su ID --> <select id="ibatis_logueo" parameterClass="java.DESARROLLO DE APLICACIONES WEB I 95 e) Paso 5: Modificar el archivo Cliente.foto from tbcliente where usuario = #value#.0//EN" "http://www.sueldo.nombre.String" resultMap="clienteRes"> select usuario. En el ejemplo.sexo.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//iBATIS.bean.ibatis.clave. 2) La etiqueta <resultMap> es utilizada cuando los nombres de las columnas de una tabla no coinciden con los atributos de la clase que recibirá los datos de una consulta. </select> . es posible crear diversos alias de clases java para ser usados dentro del archivo XML.dtd"> <sqlMap namespace="Cliente"> <!-.fecnac. Los parámetros simples que llegan a la consulta son referenciados.com//DTD SQL Map 2.Referencia al DTO --> <typeAlias alias="cli" type="aprendamos.Definimos un operacion .

return objClienteDTO. System.getSqlMapInstance(). 1 objClienteDTO=(ClienteDTO)sqlMap.println("busca por usuario usando Ibatis"). se crea una instancia de la clase SqlMapClient.out. En el ejemplo.xml) • El código de usuario a través del cual se validará el logueo.out. CARRERAS PROFESIONALES CIBERTEC . Notas: 1) A través de la clase UtilSqlConfig. el objeto sqlMap es la representación en java del archivo SqlMapConfig. 2) Se invoca al método queryForObject del objeto sqlMap. 2 System.queryForObject("ibatis_logueo ".println("Validamos con ibatis"). Se envía como parámetros lo siguiente: • El nombre de la operación que se desea ejecutar (definida en el archivo Cliente. } ... usuario).96 f) Paso 6: Modificar el archivo MySqlClienteDAO public ClienteDTO buscaPorUsuario(String usuario) throws Exception{ //Metodo modificado para Ibatis ClienteDTO objClienteDTO=null. SqlMapClient sqlMap=UtilSqlConfig.

CIBERTEC CARRERAS PROFESIONALES .DESARROLLO DE APLICACIONES WEB I 97 g) Paso 7: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo.

CARRERAS PROFESIONALES CIBERTEC .98 Se visualizará la pantalla de bienvenida de la aplicación. Se visualizará en consola el mensaje generado por la clase MySqlClienteDAO h) Paso 8: ¡Bien!. ha culminado la funcionalidad “Introducción IBATIS” exitosamente.

NET delete only) All dynamic elements insert <generate> (. es necesario conocer las principales etiquetas del Framework. CIBERTEC CARRERAS PROFESIONALES .DESARROLLO DE APLICACIONES WEB I 99 2.NET methods only) id parameterClass resultClass <procedure> parameterMap resultMap xmlResultName (Java only) insert update All dynamic elements delete All query methods Se desarrollan.2.1.NET update only) delete All dynamic elements insert <generate> (. Éstas se muestran a continuación: Sentencias Atributos id parameterClass resultClass parameterMap <statement> resultMap cacheModel xmlResultName (Java only) id parameterClass parameterMap id parameterClass parameterMap id parameterClass parameterMap id parameterClass resultClass parameterMap resultMap cacheModel Elementos Hijos Métodos insert update All dynamic elements delete All query methods <insert> All dynamic elements insert <selectKey> update <generate> (.NET update only) delete <update> <delete> <select> All dynamic elements All query <generate> (. Operaciones básicas de Acceso a base de datos con IBATIS Para implementar las operaciones básicas con IBATIS. a continuación. diversos ejercicios en los que se utilizarán y describirán las principales etiquetas del Framework.

xml .1.Map" id="clienteMap" <parameter <parameter <parameter <parameter <parameter <parameter <parameter </parameterMap> > property="nombre" jdbcType="VARCHAR" /> property="sueldo" jdbcType="DOUBLE" /> property="sexo" jdbcType="CHAR" /> property="fecnac" jdbcType="DATETIME" /> property="usuario" jdbcType="VARCHAR" /> property="clave" jdbcType="VARCHAR" /> property="foto" jdbcType="BLOB" /> Notas: 1) Al utilizar la etiqueta <parameterMap>.1.100 2. . .2. a) Paso 1: Modificar el archivo Cliente. utilizando el framework IBATIS. Ejercicio 1: Funcionalidad IBATIS .Mantenimiento Se implementará una aplicación que permita ejecutar las operaciones básicas de un mantenimiento. Note cómo se identifica cada campo de la clase Map con el tipo de dato al que se referirá en la base de datos.Map. Éste será enviado desde la clase DAO y estará representado por la clase java. CARRERAS PROFESIONALES CIBERTEC .util. <resultMap class="cli" id="clienteRes" > <result <result <result <result <result <result <result property="nombre" column="nombre" /> property="sueldo" column="sueldo" /> property="sexo" column="sexo" /> property="fecnac" column="fecnac" /> property="usuario" column="usuario" /> property="clave" column="clave" /> property="laFoto" column="foto" /> </resultMap> 1 <parameterMap class="java.util. se ha creado un párametro especial llamado clienteMap.

<select id="ibatis_clienteLista" parameterClass="java.clave.fecnac from tbcliente where nombre like #value# </select> <!-.nombre.?.foto) values (?. > 1 Notas: 1) Observe cómo la operación ibatis_insertaCliente recibe como parámetro “clienteMap” definido en líneas previas..sexo.?. CIBERTEC CARRERAS PROFESIONALES .?.sueldo.cuando utilizamos parameterMap o resultMap nuestras sentencias pueden utilizar las interrogantes de un prepareStatement tipico --> <insert id="ibatis_insertaCliente" parameterMap="clienteMap" insert into tbcliente(nombre.?.sueldo.fecnac.?.DESARROLLO DE APLICACIONES WEB I 101 Se crean las operaciones para insertar y listar clientes por nombre.clave. Los campos son automáticamente asociados a las interrogantes de la sentencia SQL..Para poner wildcards aqui en value seria '%$value$%'--> select usuario.String" resultClass="cli"> <!-.?) </insert> .sexo.lang. usuario.

.put("foto".read(losbytes). se prepara un arreglo de bytes. objCliente. int resultado =0.getSqlMapInstance(). objCliente. map.put("sueldo". return resultado. Notas: 1) A partir del campo isFoto (de tipo InputStream). 2 1 CARRERAS PROFESIONALES CIBERTEC .getClave()). cliente.println("registro exitoso con IBATIS :) ").xml.getNombre()).println("Insertando con ibatis :) "). map. objCliente. Object> map = new HashMap<String.put("nombre". map.getSueldo()). objCliente. map. objCliente.out. map. SqlMapClient cliente = UtilSqlConfig.available()]. // a partir del inputStream cargamos el arreglo los bytes is. Object>(). // intento 01: asumimos que ibatis soporta como parametro // un arreglo de bytes // Asumimos que esta llegando la foto InputStream is = objCliente.getFecnac()). el cual se carga en el objeto map con el nombre “foto”. losbytes).put("sexo". public int registraCliente(ClienteDTO objCliente) throws Exception{ System.out.. map.getIsFoto(). // En vez de enviar objCliente. } . objCliente. System.insert("ibatis_insertaCliente".getSexo()).map). enviaremos una estructura // preparada para soportar un tipo LongBloB y registrar // el cliente con IBATIS HashMap<String.102 b) Paso 2: Modificar la clase MySqlClienteDAO Se prepara la invocación a las operaciones IBATIS definidas en el archivo Cliente.put("clave". 2) Se invoca a la sentencia insert de IBATIS.getUsuario()).put("usuario". map. byte[] losbytes = new byte[is.put("fecnac". pasándole como parámetros el nombre de la operación a ejecutar y el objeto map.

DESARROLLO DE APLICACIONES WEB I 103 public List<ClienteDTO> listaPorNombre(String vnombre) throws Exception{ ArrayList<ClienteDTO> clientes= new ArrayList<ClienteDTO>(). } . "%"+vnombre+"%").out. Se visualizará la siguiente pantalla: CIBERTEC CARRERAS PROFESIONALES . System.println("Validamos con ibatis").queryForList("ibatis_cl ienteLista"...getSqlMapInstance(). return clientes.xml (como parte del parámetro like). SqlMapClient sqlMap=UtilSqlConfig. c) Paso 3: Ejecutar la aplicación Ingrese a la intranet y ejecute la funcionalidad de Listado. Note que se envía la variable vnombre junto con los caracteres “%” a ser utilizados en la consulta definida en el archivo Cliente.println("listado por nombre usando Ibatis").out. clientes=(ArrayList<ClienteDTO>)sqlMap. /** Para manejar transacciones usar las clasese de Ibatis de sqlMapClient**/ System. 1 Notas: 1) Se invoca al método queryForList para ejecutar operaciones que retornen más de un registro como resultado.

CARRERAS PROFESIONALES CIBERTEC .104 En la consola. se visualizará el mensaje definido en la clase MySqlClienteDAO. Ahora. seleccione el enlace “Nuevo Cliente” y registre uno nuevo con el botón Registrar.

DESARROLLO DE APLICACIONES WEB I 105 Se visualizará la siguiente ventana con el nuevo registro ingresado. En el ejemplo. CIBERTEC CARRERAS PROFESIONALES . se ha registrado al cliente “Don Ramón”.

d) Paso 4: ¡Bien!. se visualizará.106 También. el mensaje definido en la clase MySqlClienteDAO. CARRERAS PROFESIONALES CIBERTEC . en consola. ha culminado la funcionalidad “Mantenimiento IBATIS” exitosamente.

String "mode= "INOUT" /> <parameter property= "email2" jdbcType= "VARCHAR" javaType= "java.lang. a) Paso 1: Importar FuncionalidadIbatisProcedure_Inicial. procedure. continuación.?)) </ procedimiento> Se implementan.xml <parameterMap id= "swapParameters" class= "map"> <parameter property= "email1" jdbcType= "VARCHAR" javaType= "java.String "mode= "INOUT" /> </ parameterMap> <procedure id= "swapEmailAddresses" parameterMap= "swapParameters"> (call swap_email_address (?. Otras operaciones y características de IBATIS Los procedimientos almacenados se crean con la declaración <procedure>.1.war el archivo 1 CIBERTEC CARRERAS PROFESIONALES .lang. Ejercicio 1: Registro de Clientes utilizando Stored Procedures Se implementará una aplicación web que permita registrar los datos de un cliente (incluida su fotografía).2.DESARROLLO DE APLICACIONES WEB I 107 2. a almacenados IBATIS.2 Otras operaciones con IBATIS 2. utilizando IBATIS y Stored Procedures.2.1. El siguiente ejemplo muestra un procedimiento almacenado con parámetros de salida. ejercicios con procedimientos 2.1.

vclave.108 Notas: 1) Cuenta. select count(*) into variable from tbcliente where usuario = vusuario.sql dentro de mysql CREATE PROCEDURE `sp_nuevoCliente`( in vnombre varchar(100). in vsexo varchar(1).clave. en esta oportunidad.. in vclave varchar(15).fecnac..sueldo. vsueldo. in vfoto BLOB. vusuario. in vsueldo double. vfoto). else set resultado = 666.usuario. if variable = 0 then set resultado = 777. inout resultado int ) BEGIN declare variable int. b) Paso 2: Ejecute el archivo sp_nuevoCliente.sexo.foto) values( vnombre. insert into tbcliente(nombre. in vfecnac date. vsexo. Este archivo contiene el stored procedure que deberá crear en mysql. END $$ .sql. vfecnac. 1 CARRERAS PROFESIONALES CIBERTEC . end if. dentro de la carpeta bd con archivos adicionales dentro de los cuales destaca ps_nuevoCliente. in vusuario varchar(15).

DESARROLLO DE APLICACIONES WEB I 109 Ejecute el stored procedure. Éste debe haber sido cargado previamente en la clase MySqlClienteDAO y reconocido por el archivo Cliente. 2) Una vez ejecutado el script del stored procedure se debe visualizar su base de datos (en el ejemplo facilito) y el nombre del procedimiento creado. CIBERTEC CARRERAS PROFESIONALES . utilizando la herramienta Mysql Query Browser (u otra equivalente) 2 Notas: 1) Se recibe como parámetro un campo de tipo BLOB.xml.

read(losbytes). // a partir del inputStream cargamos el arreglo los bytes is..println("resultado despues de insertar: " + map. map).put("foto". retornará el valor 777. System. Éste permitirá recuperar el resultado retornado por el stored procedure. CARRERAS PROFESIONALES CIBERTEC . en caso de ser exitosa la operación.put("resultado". cliente. 0).get("resultado")). map. . map.out. 3) Se recupera el resultado retornado por el stored procedure: En el ejemplo. 2 1 3 Notas: 1) Se carga en el objeto map un atributo adicional: el campo resultado. System.insert("ibatis_spInsertaCliente"..110 c) Paso 3: Modifique el método registraCliente dentro de la clase MySqlClienteDAO byte[] losbytes = new byte[is. 2) Se debe invocar a una nueva operación definida en el archivo Cliente.println("resultado antes de insertar: " + map. de lo contrario regresará a 666.get("resultado")). losbytes).out. System. return resultado.out.xml: ibatis_spInsertaCliente.available()].println("invocacion exitosa a SP IBATIS :) ").

?.map es mapeado a una columna en la tabla de tipo BLOB: jdbcType=”BLOB” 3) Note qué resultado es la única propiedad de tipo INOUT.?. 4) Debe invocar al stored procedure creado en base de datos a través de la sentencia call.DESARROLLO DE APLICACIONES WEB I 111 d) Paso 4: Modifique el archivo Cliente.util. si el parámetro es de entrada o entrada/salida.?) </procedure> Notas: 1) Se debe modificar cada una de las etiquetas <parameter> para indicar.util. 3 > 4 CIBERTEC CARRERAS PROFESIONALES . A través de ella.xml <parameterMap class="java.. a través del atributo mode.?.. <procedure id="ibatis_spInsertaCliente" parameterMap="clienteMap" call sp_nuevoCliente(?.Map" id="clienteMap" <parameter <parameter <parameter <parameter <parameter <parameter <parameter <parameter /> > 1 property="nombre" jdbcType="VARCHAR" mode="IN" /> property="sueldo" jdbcType="DOUBLE" mode="IN" /> property="sexo" jdbcType="CHAR" mode="IN" /> property="fecnac" jdbcType="DATETIME" mode="IN" /> property="usuario" jdbcType="VARCHAR" mode="IN" /> property="clave" jdbcType="VARCHAR" mode="IN" /> property="foto" jdbcType="BLOB" mode="IN" /> property="resultado" jdbcType="INT" mode="INOUT" 2 </parameterMap> .?.?. Note que usa la etiqueta IBATIS <prodecure> para definir la operación ibatis_spInsertaCliente.?. se retornará al MySqlClienteDAO el resultado de la ejecución del stored procedure. 2) Note cómo el arreglo de bytes cargado con el nombre foto en el objeto java.

se visualizará la siguiente pantalla: CARRERAS PROFESIONALES CIBERTEC . Visualizará la siguiente pantalla: Luego de ingresar datos y seleccionar el botón Registrar.112 e) Paso 5: Ejecute la aplicación Seleccione la opción Nuevo Cliente una vez realizado el listado de Clientes.

xwork2.CommonsLogger warn f) Paso 6: ¡Muy Bien!.core\tmp0\work\Catalina\localhost\FuncionalidadIBatisP rocedure_Final\upload__2a3c5961_12db5077826__8000_00000006.tmp 23/01/2011 05:38:41 PM com.wst .CommonsLogger INFO: Removing file cliente. los siguientes mensajes: Insertando con ibatis :) resultado antes de insertar: 0 resultado despues de insertar: 777 invocacion exitosa a SP IBATIS :) dentro del listaCliente del Service Validamos con ibatis listado por nombre usando Ibatis 23/01/2011 05:38:41 PM com.server.util. en la consola de Eclipse.eclipse.DESARROLLO DE APLICACIONES WEB I 113 Se visualizará también.xwork2.logging.commons. ha culminado exitosamente la funcionalidad “Registro de Clientes con Stored Procedures e IBATIS”. CIBERTEC CARRERAS PROFESIONALES .util.foto C:\Users\plgarcia\workspace\.opensymphony.plugins\org.logging.metadata\.opensymphony.commons.

un ejemplo con Stored Procedures que utiliza este tipo de estructuras. a continuación. los campos BLOB y CLOB. IBATIS es capaz de gestionar objetos grandes (LOB).2. 2.sql y sp_modificaClienteConFoto.1. tales como los campos BLOB (Binary) o CLOB (de caracteres).sql CARRERAS PROFESIONALES CIBERTEC .1.0. A partir de la versión de IBATIS 2.9. Ejercicio 1: Actualización de Clientes utilizando Stored Procedures a) Paso 1: Ubique los Stored Procedures relacionados con la actualización de datos de un cliente almacenados en la carpeta bd de su proyecto. Se implementa.1.114 2. por defecto. Tópicos Avanzandos de IBATIS e integración Struts 2 Es cada vez más común utilizar estructuras de base de datos capaces de almacenar grandes cantidades de información. 1 Notas: 1) Observe que debe ejecutar los archivos sp_modificaCliente. este framework cuenta.2.

select count(*) into variable from tbcliente where usuario = vusuario. else set resultado = 666. 1 CIBERTEC CARRERAS PROFESIONALES . END $$ . update tbcliente set nombre=vnombre. in vsexo varchar(1).sql y sp_modificaClienteConFoto. inout resultado int ) BEGIN declare variable int.sql dentro del entorno MySql CREATE PROCEDURE `sp_modificaCliente`( in vnombre varchar(100). in vclave varchar(15). fecnac=vfecnac. sexo=vsexo. in vusuario varchar(15).. sueldo=vsueldo.. in vsueldo double. in vfecnac date. end if. if variable != 0 then set resultado = 777. clave=vclave where usuario=vusuario.DESARROLLO DE APLICACIONES WEB I 115 b) Paso 2: Ejecute los archivos sp_modificaCliente.

116

CREATE PROCEDURE `sp_modificaClienteConFoto`( in vnombre varchar(100), in vsueldo double, in vsexo varchar(1), in vfecnac date, in vusuario varchar(15), in vclave varchar(15), in vfoto BLOB, inout resultado int ) BEGIN declare variable int; select count(*) into variable from tbcliente where usuario = vusuario; if variable != 0 then set resultado = 777; update tbcliente set nombre=vnombre, sueldo=vsueldo, sexo=vsexo, fecnac=vfecnac, clave=vclave, foto=vfoto where usuario=vusuario; else set resultado = 666; end if;

2

END $$ ...

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

117

En el ejemplo, se ha utilizado la herramienta MySql WorkBench para ejecutar los Stored Procedures.

3

Notas: 1) La sentencia update no considera en su ejecución la actualización de la columna foto. Este procedure será invocado cuando el usuario del sistema no desee actualizar la fotografía del cliente. 2) Este procedure sí recibe como parámetro un campo denominado vfoto, de modo que se pueda actualizar la imagen del cliente. 3) Una vez ejecutados los procedures dentro de la herramienta gráfica de Mysql éstos se visualizan en la ventana de edición. En el ejemplo, en la ventana Object Browser.

CIBERTEC

CARRERAS PROFESIONALES

118

c) Paso 3: Modifique el método registraCliente dentro de la clase MySqlClienteDAO

HashMap<String, Object> map = new HashMap<String, Object>(); map.put("nombre", objCliente.getNombre()); map.put("sueldo", objCliente.getSueldo()); map.put("sexo", objCliente.getSexo()); map.put("fecnac", objCliente.getFecnac()); map.put("usuario", objCliente.getUsuario()); map.put("clave", objCliente.getClave()); if (objCliente.getFoto() != null) { InputStream is = objCliente.getIsFoto(); byte[] losbytes = new byte[is.available()]; // a partir del inputStream cargamos el arreglo los bytes is.read(losbytes); map.put("foto", losbytes); } map.put("resultado", 0); System.out.println("resultado antes de actualizar: " + map.get("resultado")); SqlMapClient cliente = UtilSqlConfig.getSqlMapInstance(); if (objCliente.getFoto() != null) { cliente.update("ibatis_spModificaClienteConFoto", map); }else{ cliente.update("ibatis_spModificaCliente", map); } System.out.println("resultado despues de actualizar: " + map.get("resultado")); System.out.println("invocacion exitosa a SP MOD IBATIS :) "); } ...
Notas: 1) Solo se carga en el objeto map el atributo foto, si éste es diferente de null. En el ejemplo, se controla esta situación a través de la condición: 3

1

2

if (objCliente.getFoto() != null)

CARRERAS PROFESIONALES

CIBERTEC

d) Paso 4: Modifique el archivo Cliente.?.?.?) </procedure> <procedure id="ibatis_spModificaCliente" parameterMap="clienteMapBasico" > call sp_modificaCliente(?.?) </procedure> Notas: 1) Se ha creado un nuevo parameterMap: clienteMapBasico. que será utilizado para actualizar la información del cliente sin modificar su fotografía. 3) Se recupera el resultado retornado por el stored procedure: En el ejemplo.?.util.?. <procedure id="ibatis_spModificaClienteConFoto" parameterMap="clienteMap" > call sp_modificaClienteConFoto(?..Map" id="clienteMap" > <parameter property="nombre" jdbcType="VARCHAR" mode="IN" /> <parameter property="sueldo" jdbcType="DOUBLE" mode="IN" /> <parameter property="sexo" jdbcType="CHAR" mode="IN" /> <parameter property="fecnac" jdbcType="DATETIME" mode="IN" /> <parameter property="usuario" jdbcType="VARCHAR" mode="IN" /> <parameter property="clave" jdbcType="VARCHAR" mode="IN" /> <parameter property="foto" jdbcType="BLOB" mode="IN" /> <parameter property="resultado" jdbcType="INT" mode="INOUT" /> </parameterMap> .xml <parameterMap class="java. 1 2 3 CIBERTEC CARRERAS PROFESIONALES .DESARROLLO DE APLICACIONES WEB I 119 2) Se invocará a una nueva operación: ibatis_spModificaClienteConFoto o ibatis_spModificaCliente.util.?.?. retornará el valor 777.?.?.?.?. de lo contrario regresará a 666..?.Map" id="clienteMapBasico" > <parameter property="nombre" jdbcType="VARCHAR" mode="IN" /> <parameter property="sueldo" jdbcType="DOUBLE" mode="IN" /> <parameter property="sexo" jdbcType="CHAR" mode="IN" /> <parameter property="fecnac" jdbcType="DATETIME" mode="IN" /> <parameter property="usuario" jdbcType="VARCHAR" mode="IN" /> <parameter property="clave" jdbcType="VARCHAR" mode="IN" /> <parameter property="resultado" jdbcType="INT" mode="INOUT" /> </parameterMap> <parameterMap class="java. en caso de ser exitosa la operación.

se visualizará la siguiente pantalla: CARRERAS PROFESIONALES CIBERTEC . respectivamente. seleccione el enlace “M” para modificar uno de los clientes. e) Paso 5: Ejecute la aplicación Una vez realizado el listado de clientes. 3) Se han creado dos nuevas operaciones en el archivo Cliente.120 2) Se mantiene el parameterMap clienteMap para actualizar la información del cliente modificando su fotografía.xml que serán invocadas por la clase MySqlClienteDAO para modificar la información del cliente modificando o no su fotografía. Se visualizará la siguiente pantalla: Luego de modificar los datos y seleccionar el botón Actualizar. En el ejemplo. se cambian los datos de Don Ramón.

DESARROLLO DE APLICACIONES WEB I 121 1 Nota: 1) Puede seleccionar nuevamente el enlace “M” para verificar los cambios realizados. CIBERTEC CARRERAS PROFESIONALES . Visualizará que se logró modificar exitosamente la fotografía de “Don Ramón”.

122 f) Paso 6: ¡Muy Bien!. de Clientes con Stored CARRERAS PROFESIONALES CIBERTEC . ha culminado exitosamente la funcionalidad “Actualización Procedures e IBATIS”.

com/javaworld/jw-07-2008/jw-07-orm-comparison.com/iBATIS-f360.html Aquí hallará comparaciones entre los frameworks de persistencia más utilizados. puede hacer lo siguiente: Map hashCoche = (Map) sqlMap. CIBERTEC CARRERAS PROFESIONALES . puede hacer lo siguiente: List<Coche> coches = sqlMap.javaworld.queryForObject("getHashCoche". se tiene que realizar lo siguiente en el archivo de Ibatis: <resultMap class= <result <result <result <result /> </ resultMap> "Report" id= "ReportResult"> column= "id" property= "id" /> column= "name" property= "name" /> column= "description" property= "description" /> column= "data" property= "data" jdbcType= "BLOB" Si desea saber más acerca de estos temas.DESARROLLO DE APLICACIONES WEB I 123 Resumen Para recoger un conjunto de elementos con la clase List. http://www. null) Para recoger un conjunto de elementos con la clase Map.html Aquí encontrará un foro donde se ventilan varios puntos del manejo de Ibatis http://www. 3). Para el manejo del campo BLOB. puede consultar la siguiente página.queryForList("getCoches".nabble.

124

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

125

UNIDAD DE APRENDIZAJE

3

REPORTES EN SISTEMAS EMPRESARIALES
LOGRO DE LA UNIDAD DE APRENDIZAJE
• Al finalizar la unidad, los alumnos, utilizando el framework STRUTS 2, la librería JasperReport y la herramienta IReport, implementan una aplicación web que genera reportes con criterios de búsqueda dinámicos y acceso a base de datos.

TEMARIO 3.1 Tema 5 3.1.1. : Reportes con JasperReport : Diseño e implementación de reportes con la herramienta IReport : Struts 2 y JasperReport : Integración de Struts 2 y JasperReport – Reportes Estándar

3.2 Tema 6 3.2.1.

ACTIVIDADES PROPUESTAS • Los alumnos implementan una aplicación web básica utilizando las principales características del framework MVC Struts 2 y la librería jasperReport.

CIBERTEC

CARRERAS PROFESIONALES

126

3.1 Reportes con JasperReport
3.1.1. Diseño e implementación de Reportes con la herramienta IReport
La herramienta iReport es un constructor y/o diseñador de reportes visual, fácil de usar para JasperReport, un lenguaje para generación de reportes escrito en Java. Esta herramienta permite que los usuarios corrijan visualmente reportes complejos con cartas, imágenes, subreportes, etc. iReport está, además, integrado con la biblioteca gráfica “JFreeChart”, una de las más gráficas OpenSource y difundida para Java. Los datos para imprimir pueden ser recuperados por varios tipos de archivos, incluso múltiples uniones JDBC, TableModels, JavaBeans, archivos XML, etc. A continuación, se enumeran las principales características de esta herramienta: 100% escrito en JAVA y, además, de uso libre y gratuito Maneja el 99% de las etiquetas de JasperReports Permite diseñar con sus propias herramientas: rectángulos, líneas, elipses, campos de los textfields, cartas, subreports (subreportes) Soporta internacionalización nativamente Recopila y exporta integrados Soporta JDBC Soporta JavaBeans como orígenes de datos Incluye asistentes para crear automáticamente informes.

3.1.1.1. Funcionamiento de JasperReport JasperReports trabaja en forma similar a un compilador y a un intérprete. El usuario diseña el reporte codificándolo en XML de acuerdo con las etiquetas y atributos definidos en un archivo llamado jasperreports.dtd (parte de JasperReports). Usando XML, el usuario define completamente el reporte, describiendo dónde colocar texto, imágenes, líneas, rectángulos, cómo adquirir los datos, cómo realizar ciertos cálculos para mostrar totales, etc. Este archivo fuente XML debe ser compilado para obtener un reporte real. La versión compilada del fuente es nombrada "archivo jasper" (este termina con .jasper). Un Archivo jasper es el compilado de un código fuente. Cuando se tiene éste, se necesita de datos para visualizar el resultado. Para generar reportes en Java, se necesita considerar la aplicación del archivo compilado (.jasper), que recibirá los datos a visualizar de la aplicación. El archivo generado por la herramienta iReport es de tipo “jrxml”, en el cual se encontrará el diseño y estilo del reporte, y podrá ser modificado en la herramienta iReport.

CARRERAS PROFESIONALES

CIBERTEC

Ejercicio 01: Funcionalidad Reporte de clientes con JasperReport Se implementará una aplicación web que permita listar los clientes por País.xml un nuevo tipo de <result>: jasper Se implementará. a) Paso 1: Importar el archivo FuncionalidadIbatisReportes_Inicial.1.1.jar Esta librería viene por defecto con la versión estándar de Struts 2 y permite crear en el archivo struts.jasper) y Struts 2. haciendo uso de la librería JasperReport e integrándola a Struts 2.2.DESARROLLO DE APLICACIONES WEB I 127 3. un ejercicio de aplicación.war CIBERTEC CARRERAS PROFESIONALES .1. Integración de Struts 2 y JasperReport – Reportes Estándar Struts 2 permite implementar una integración natural con JasperReport a través del uso de una librería (plug in): struts2-jasperreports-plugin-2. 3.1. en el que se integra un reporte generado con la herramienta IReport (archivo compilado .8.2 Struts 2 y JasperReport 3. a continuación.1.2.

se encontrarán nuevas tablas.sql. En él.sql dentro de mysql CARRERAS PROFESIONALES CIBERTEC . 2) Existen nuevas librerías en la carpeta lib que permitirán integrar Struts 2 y JasperReport. b) Paso 2: Ejecute el archivo FacilitoBaseDatosv2.128 1 2 Notas: 1) Existe un nuevo archivo en la carpeta bd denominado FacilitoBaseDatosv2. a partir de las cuales se generará el reporte.

primary key (`cod_pais`) ) ENGINE=InnoDB default CHARSET=latin1. `password` varchar(15) not null. `fecha_ingreso` datetime null. primary key (`usuario`) Notas: 1) Debe crear las tablas cliente y país en MySql. `nom_pais` varchar(90) not null. `sexo` varchar(1) not null.DESARROLLO DE APLICACIONES WEB I 129 create table pais ( `cod_pais` varchar(2) not null. `flag_admin` varchar(1) not null default 'N'. `vip` varchar(1) not null. b) Paso 3: Modificar el archivo struts. `nombres` varchar(90) null.xml CIBERTEC CARRERAS PROFESIONALES . `apellidos` varchar(90) null. Sobre la base de estas tablas. 1 create table cliente ( `usuario` varchar(15) not null. se generará el nuevo reporte. `cod_pais` varchar(2) null. `fecha_nacimiento` datetime null. `dni` varchar(8) null. `email` varchar(80) null.

ReporteAction" method="listaClientesPorPais" > <result name="exito" type="jasper"> <param name="location">/reportes/reporte01.apache. usando JasperReport. <result-types> <result-type name="jasper" 1 class="org. . 3) Cree un nuevo action: reporteFacilito. <action name="reporteFacilito" class="aprendamos.pdf" </param> <param name="format">PDF</param> <!--<param name="connection">cnListaClientes</param> -> d_reporte </result> Notas: 1) Debe crear un nuevo result type para poder integrar jasperReport y Struts 2. .struts2.130 . .java.JasperReportsR esult"/> </result-types> 2 <!-.jasper</param> <param name="dataSource">listaClientes</param> <param name="contentDisposition"> attachment. 2) Cree el action a_reporte para invocar a un nuevo definition: d_reporte.creamos los actions del menu --> <action name="a_reporte" > <result type="tiles" >d_reporte</result> </action> . .action.filename="contacts. Este componente define un <result> de tipo jasper en donde se configuran los principales parámetros del reporte como por ejemplo: • • • Formato del archivo a generar: PDF Ubicación de archivos compilado ejecutar: /reportes/reporte01. Éste invocará a una página JSP para generar el reporte. .jasper a 3 el listado CARRERAS PROFESIONALES CIBERTEC .jasper Origen de datos para generar (dataSource): atributo listaClientes.views.jasperreports.

Notas: 1) Debe invocar al action reporteFacilito. debe generar el listado con jasperreport.nombre" /> </td> <td> <s:textfield name="nombre" /> </td> <td align="right" > <input type="submit" name="boton01" value="Listar" > </td> </tr> </table> </s:form>su ID --> 1 . Asimismo.. 1 Notas: 1) Cree el definition d_reporte.jsp <s:form method="post" action="reporteFacilito"> <table class="control" > <tr> <td> <s:text name="reporte..jsp" /> </definition> . el cual ya ha sido registrado en el archivo struts.xm.xml <definition name="d_reporte" extends="d_bienvenida"> <put-attribute name="body" value="/paginas/reportes.. Se invocará al JSP reportes.DESARROLLO DE APLICACIONES WEB I 131 d) Paso 4: Modificar el archivo tiles.. f) Paso 6: Cree el action ReporteAction CIBERTEC CARRERAS PROFESIONALES .jsp e) Paso 5: Cree el archivo reportes.

nombre = nombre.xml como origen de datos para el Reporte. Esta clase tiene como atributos los campos que serán mostrados en el reporte. } public void setNombre(String nombre) { this.FORMAT_PDF //JasperReportConstants. 2) Se define la lista de clientes a obtener.println("redireccionamos a la vista exito!"). 1 public List<ReporteDTO> getListaClientes() { return listaClientes.printStackTrace().println("dentro de listaClientesPorPais :)"). } catch (Exception e) { // TODO Auto-generated catch block e.. listaClientesReporte(nombre)). } public String listaClientesPorPais(){ String vista="exito".FORMAT_XLS System.setListaClientes( PaqueteBusinessDelegate. //JasperReportConstants. Note que es una lista de objetos de tipo ReporteDTO.listaClientes = listaClientes.out. private List<ReporteDTO> listaClientes.132 public class ReporteAction { private String nombre.out.FORMAT_HTML //JasperReportConstants. return vista. considerando la selección del usuario (el atributo nombre). } } .getClienteService(). } System. } public String getNombre() { return nombre.getNombre()).println("nombre del cliente"+this. } public void setListaClientes(List<ReporteDTO> listaClientes) { this. 2 CARRERAS PROFESIONALES CIBERTEC . System..out. try { this. Notas: 1) El atributo listaClientes es referenciado en el archivo struts.

DESARROLLO DE APLICACIONES WEB I 133 g) Paso 7: Modifica la clase ClienteService public List<ReporteDTO> listaClientesReporte(String nombre) throws Exception{ System..listaPorNombreReporte(nombre). CIBERTEC CARRERAS PROFESIONALES .. 1 Notas: 1) Debe crear el método listaClientesReporte para que la clase ReporteAction pueda invocarlo y generar el reporte. // Aqui podemos colocar logica adicional antes de invocar al metodo // del DAO return objClienteDAO.out.println("dentro del listaCliente del Service"). .

//ejecutamos ResultSet rs=pst. clientes. cliente. cliente. cliente.cod_pais".setNom_pais(rs.nombres like and c.pais p WHERE c.prepareStatement(sql).password. cliente.setPassword(rs.jsp CARRERAS PROFESIONALES CIBERTEC .add(cliente). recuperamos un ergsitro ReporteDTO cliente = new ReporteDTO().apellidos.setString(1.getString(1)). se obtiene una conexión para hacer la consulta respectiva. c. 1 ? Notas: 1) Note cómo. while(rs.sexo.obtenerConexion().getString(7)). } . cliente.setSexo(rs. } cn. Debe transformar este código a su equivalente en ibatis. return clientes.fecha_nacimiento. //definimos la sentencia String sql="SELECT usuario. //asignamos valores a las interrogantes pst.getString(9)).cod_pais = p.executeQuery().setNombres(rs.nombres.getString(8)).getString(3)).dni.getString(6)). de manera “clásica”. cliente.nom_pais" + " FROM cliente c.p."%"+nombre+"%").getString(5)). i) Paso 9: Modifique el archivo menu.getString(2)).134 h) Paso 8: Modificar el archivo MySqlClienteDAO public List<ReporteDTO> listaPorNombreReporte(String nombre) throws Exception { ArrayList<ReporteDTO> clientes= new ArrayList<ReporteDTO>().cod_pais order by c.setFecha_nacimiento(rs.. cliente.setDni(rs. cliente.getString(4)). Connection cn = MySqlDBConn. //la preparamos PreparedStatement pst=cn.setCod_pais(rs.next()){ //hay dayos.setUsuario(rs.cod_pais..setApellidos(rs.close(). cliente.

Se visualizará la siguiente pantalla: Seleccione la opción reporte utilizando JasperReport CIBERTEC CARRERAS PROFESIONALES . Notas: 1) Debe invocar al action a_reporte para cargar la página JSP a partir de la cual se generará el reporte..DESARROLLO DE APLICACIONES WEB I 135 <tr> <td class="control" > <s:a action="a_reporte" > /> 1 <s:text name="menu.reporte" </s:a> </td> </tr> .. i) Paso 10: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo.

Seleccione abrir el archivo.136 Se visualizará la siguiente pantalla. seleccione el botón Listar. ingrese un criterio de búsqueda. Luego. Finalmente. Visualizará el reporte en una pantalla similar a la siguiente: CARRERAS PROFESIONALES CIBERTEC . Visualizará una pantalla a través de la que se le consultará si desea abrir o guardar el archivo.

ha culminado la funcionalidad “reportes con JasperReport y Struts 2” de manera exitosa! CIBERTEC CARRERAS PROFESIONALES .DESARROLLO DE APLICACIONES WEB I 137 j) Paso 11: ¡Muy Bien!.

puede consultar la siguiente página.jasper y pueden ser ejecutados desde una aplicación java web. encontrará tutoriales que le permitirán crear reportes utilizando IReport. http://jasperforge.jrxml. Ésta usa como estructura base jasperReport. IReport genera archivos fuente con extensión .org/website/ireportwebsite/IR%20Website/iReport_documentati on. Los archivos compilados tienen extensión . CARRERAS PROFESIONALES CIBERTEC .html?group_id=243&header=project&leftnav=yes&target=ireport Aquí. un lenguaje basado en etiquetas xml y especialmente creado para generar reportes.138 Resumen Se pueden construir reportes visualmente en Java. utilizando la herramienta iReport. Si desea saber más acerca de estos temas.

DESARROLLO DE APLICACIONES WEB I 139 ANEXOS ANEXO 1: SOFTWARE REQUERIDO Este curso requiere las siguientes herramientas de software: • • • • • • • Java JDK Entorno integrado de desarrollo o IDE Servidor de Aplicaciones Base de datos Framework Struts 2 Framework MyIbatis MyIbatis Generator CIBERTEC CARRERAS PROFESIONALES .

140 HERRAMIENTA #1: Java Development Kit Desde la página de Oracle. el cual redirecciona a http://www. descargue la última versión del JDK (Java Development Kit). se requiere el JDK. Por último. CARRERAS PROFESIONALES CIBERTEC .sun.html Para entornos de programación.com/technetwork/java/javase/downloads/index.com. ejecute el instalador y siga los pasos indicados en el wizard. Se debe considerar que los “updates” de las versiones son periódicos. pero para los de producción basta con el JRE. Se puede navegar por http://java.oracle.

org JDeveloper : Información disponible en http://www.com Rational Application Developer: Información disponible en http://www. seleccione la versión Java EE: Al terminar la descarga. descargue Eclipse Helios desde la página de la fundación Eclipse ( http://www.DESARROLLO DE APLICACIONES WEB I 141 HERRAMIENTA #2: Entorno Integrado de Desarrollo En un entorno de desarrollo Java. el . busque la zona de descarga. el IDE ( Integrated Development Environment ) es la herramienta de software que permite obtener mayor productividad al programar las aplicaciones.com Eclipse IDE: Primero.exe CIBERTEC CARRERAS PROFESIONALES . Se puede crear un acceso directo desde el Escritorio apuntando al archivo eclipse. existen varias opciones disponibles.org NetBeans : Sitio web http://www. En el mercado. pero las más utilizadas y conocidas son las siguientes: • • • • Eclipse IDE : Sitio web http://www.ibm. Por último. Luego.org ).netbeans.eclipse.eclipse.oracle.ZIP generado se puede extraer en una carpeta cualquiera (normalmente en la raíz de uno de los discos de la PC).

142 Rational Application Developer IDE : Descargue el software “IBM Rational Application Developer for WebSphere Software” desde la página web de IBM: http://www.com/developerworks/downloads/r/rad/?S_CMP=TRIALS CARRERAS PROFESIONALES CIBERTEC .ibm.

se puede descargar el software del servidor de aplicaciones: http://www-01. Actualmente se encuentra disponible la versión 7 en beta.com/software/webservers/appserv/was/ CIBERTEC CARRERAS PROFESIONALES .org ). La última versión probada en otros tutoriales ha sido la 6.20. Descargar el .0.DESARROLLO DE APLICACIONES WEB I 143 HERRAMIENTA #3: Servidor de aplicaciones Apache Tomcat Desde la página de la Fundación Apache ( http://tomcat.ZIP y extraerlo en una carpeta. Sólo es necesario el “Core”.ibm. WebSphere Application Server Desde la página web de IBM. se debe obtener el servidor de aplicaciones Tomcat.apache.

144 CARRERAS PROFESIONALES CIBERTEC .

com. El servicio de base de datos se activa por línea de comandos de la manera siguiente: CIBERTEC CARRERAS PROFESIONALES . se puede decargar la Base de Datos MySQL (versión “Community Server” ) Es preferible descargar la versión “NO-INSTALL” para que no afecte el registry de la PC: Basta con descargar el .ZIP y extraerlo en cualquier carpeta.mysql.DESARROLLO DE APLICACIONES WEB I 145 HERRAMIENTA #4: Motor de Base de Datos Se necesita un motor de base de datos: En http://www.

ZIP ( que sea del tipo “No Install” ) y extraerlo en alguna carpeta de la PC.146 También. seleccionar el . CARRERAS PROFESIONALES CIBERTEC . se requiere el “Connector” o driver JDBC: Las herramientas de Query Browser y MySQL Administrator han sido reemplazadas por MySQL WorkBench: De igual forma.

Extraer el contenido del .ZIP. CIBERTEC CARRERAS PROFESIONALES .ZIP en una carpeta de la PC. es más que suficiente. se obtienen las librerías del framework Struts 2 La última versión liberada es la 2.2. Con la alternativa de “Full Distribution”.DESARROLLO DE APLICACIONES WEB I 147 HERRAMIENTA #5: Librerías de Struts 2 Del sitio web de la Fundación Apache.1 Se debe escoger una de las opciones de los archivos .

google.mybatis.148 HERRAMIENTA #6: MyIbatis La página principal se encuentra en http://www. la dirección es http://code.com/p/mybatis/ CARRERAS PROFESIONALES CIBERTEC .org/ En la zona de downloads.

3.DESARROLLO DE APLICACIONES WEB I 149 HERRAMIENTA #7: MyIbatis Generator La página principal se encuentra: http://code.1-bundle.google.com/p/mybatis/downloads/detail?name=mybatis-generator-core1.zip&can=3&q=Product%3DGenerator CIBERTEC CARRERAS PROFESIONALES .

150 CARRERAS PROFESIONALES CIBERTEC .

DESARROLLO DE APLICACIONES WEB I 151 ANEXOS ANEXO 2: MANEJO DE MYIBATIS Ejemplo de una aplicación con MyIbatis CIBERTEC CARRERAS PROFESIONALES .

152 La Clase entidad CARRERAS PROFESIONALES CIBERTEC .

DESARROLLO DE APLICACIONES WEB I 153 El Data Access Object para Vendedor CIBERTEC CARRERAS PROFESIONALES .

154 El Mapper de MyIbatis para el mantenimiento de vendedor es el siguiente: CARRERAS PROFESIONALES CIBERTEC .

DESARROLLO DE APLICACIONES WEB I 155 El Archivo de Configuración de MyIbatis • los datos de la cadena de conexión • los tipos de datos de los mappers • la ubicación de los mappers Se configura Se configura Se configura CIBERTEC CARRERAS PROFESIONALES .

156 CARRERAS PROFESIONALES CIBERTEC .

DESARROLLO DE APLICACIONES WEB I 157 ANEXOS ANEXO 3: MYIBATIS DynamicSQL Una de las características más potentes de MyBatis siempre ha sido su capacidad de SQL dinámico. • If • choose (when. sin duda. similares a base procesadores de texto. que se pueden utilizar dentro de cualquier mapa instrucciónSQL.name != null”> AND title like #{author. otherwise) • trim (where. Asimismo.name} </if> </select> CIBERTEC CARRERAS PROFESIONALES . emplea potentes expresiones OGNL base para eliminar la mayoría de los demás elementos. MyBatis. mejora la situación en el lenguaje SQL. M ejora en gran medida en esto y ahora hay menos de la mitad de esos elementos para trabajar. set) • foreach Ejemplo de if: <select id=”findActiveBlogWithTitleLike” parameterType=”Blog” resultType=”Blog”> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test=”title != null”> AND title like #{title} </if> </select> <select id=”findActiveBlogLike” parameterType=”Blog” resultType=”Blog”> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test=”title != null”> AND title like #{title} </if> <if test=”author != null and author. Los elementos de SQL dinámico debe ser familiar para cualquiera que haya usado JSTL o cualquier XML. En versiones anteriores de MyBatis. había una gran cantidad de elementos para conocer y comprender.

when.name != null”> AND title like #{author. otherwise <select id=”findActiveBlogLike” parameterType=”Blog” resultType=”Blog”> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test=”title != null”> AND title like #{title} </when> <when test=”author != null and author. where.name} </if> </select> <select id=”findActiveBlogLike” parameterType=”Blog” resultType=”Blog”> SELECT * FROM BLOG <where> <if test=”state != null”> state = #{state} </if> <if test=”title != null”> AND title like #{title} </if> <if test=”author != null and author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select> trim.name != null”> AND title like #{author. set <select id=”findActiveBlogLike” parameterType=”Blog” resultType=”Blog”> SELECT * FROM BLOG WHERE <if test=”state != null”> state = #{state} </if> <if test=”title != null”> AND title like #{title} </if> <if test=”author != null and author.name != null”> AND title like #{author.blog." close=")"> #{item} </foreach> </select> CARRERAS PROFESIONALES CIBERTEC .158 choose.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator=".name} </if> </where> </select> Foreach <select id="selectPostIn" resultType="domain.

map.xml) DTD: <!DOCTYPE mapper PUBLIC "-//mybatis.0: <settings x="y" foo="bar"/> MyIbatis 3.0: <settings> <setting name="x" value="y"/> <setting name="foo" value="bar"/> </settings> y CIBERTEC CARRERAS PROFESIONALES .org/dtd/mybatis-3-mapper.0//EN" "http://mybatis.org/dtd/mybatis-3-config.X HACIA MYIBATIS En el sqlMapConfig.org//DTD Mapper 3.0//EN" "http://mybatis.DESARROLLO DE APLICACIONES WEB I 159 ANEXOS ANEXO 3: DE IBATIS 2.dtd"> Configuración: • La raíz era <sqlMapConfig>. ahora es <configuration> Settings Ibatis 2.org//DTD Config 3.dtd"> En los mappers sqlMap (*.xml DTD: <!DOCTYPE configuration PUBLIC "-//mybatis.

</settings> <typeAliases> <typeAlias .package....0: <environments default="env"> <environment id="env"> <transactionManager type="JDBC"> <property name="commitRequired" value="false"/> </transactionManager> <dataSource type="your.CustomDataSourceFactory" /> </environment> </environments> <sqlMap> CARRERAS PROFESIONALES CIBERTEC .package. /> </typeAliases> </configuration> <transactionManager> <dataSource> Ibatis 2.0: <transactionManager type="JDBC" commitRequired="false"> <dataSource type="your.CustomDataSourceFactory" /> </transactionManager> MyIbatis 3..160 <settings useStatementNamespaces="true"/> <typeAlias> <typeAlias> deberia ser movido fuera de <sqlMap> hacia <configuration> <typeAliases></typeAliases> </configuration> <configuration> <settings> .

0: <sqlMap resource=..0: <resultMap id="productRM" class="product" groupBy="id"> <result property="id" column="product_id"/> <result property="name" column="product_name"/> <result property="category" column="product_category"/> <result property="subProducts" resultMap="Products.0: <mappers> <mapper resource=..DESARROLLO DE APLICACIONES WEB I 161 Ibatis 2.. /> <sqlMap resource=.subProductsRM"/> </resultMap> CIBERTEC CARRERAS PROFESIONALES ... Ibatis 2. /> <sqlMap resource=. /> </mappers> Mapping • • • • • • La raiz del elemento <sqlMap> es ahora <mapper> El atributo parameterClass debería ser cambiado por parameterType El atributo resultClass debería ser cambiado por resultType El atributo class debería ser cambiado por type El columnIndex atributo no existe algun resultado en la etiqueta <result> El groupBy atributo debería ser eliminado.subProductsRM"/> </resultMap> MyIbatis 3. /> MyIbatis 3...0: <resultMap id="productRM" type="product" > <id property="id" column="product "/> <result property="name " column="product_name "/> <result property="category " column="product_category "/> <collection property="subProducts" resultMap="Products..

..0: jdbcType="ORACLECURSOR" MyIbatis 3.0: #value# MyIbatis 3.0: <resultMap .clientRM"/> .0: jdbcType="CURSOR" CARRERAS PROFESIONALES CIBERTEC ..0: <resultMap ... </resultMap> Inline parameters Ibatis 2.> <association property="client" resultMap="Client.162 Nested resultMaps Édebería especificarse mediante <association> tag..> <result property="client" resultMap="Client. </resultMap> MyIbatis 3..0: #{value} jdbcType changes Ibatis 2.clientRM"/> . Ibatis 2..

Ibatis 2.0: <select id="getValues" parameterMap="getValuesPM" statementType="CALLABLE"> { ? = call pkgExample.getValues(p_id => ?) } </procedure> MyIbatis 3.DESARROLLO DE APLICACIONES WEB I 163 Ibatis 2.0: <cacheModel id="myCache" type="LRU"> <flushInterval hours="24"/> <property name="size" value="100" /> </cacheModel> MyIbatis 3.0: jdbcType="NUMBER" MyIbatis 3.getValues(p_id => ?)} </select> Caching Ibatis 2. Use <select>.0: <procedure id="getValues" parameterMap="getValuesPM"> { ? = call pkgExample. <insert> o <update>.0: <cache flushInterval="86400000" eviction="LRU"/> CIBERTEC CARRERAS PROFESIONALES .0: jdbcType="NUMERIC" Stored procedures • La etiqueta <procedure> no existe en MyIbatis.

0: <isNotNull.0: <if test="$1 != null"> </if> CARRERAS PROFESIONALES CIBERTEC .*?property=\"(.*?)\"> </isNotNull> MyIbatis 3.164 Dynamic SQL Ibatis 2.

Sign up to vote on this title
UsefulNot useful