Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Desarrollo en J2EE (JSF + Hibernate) PDF
Desarrollo en J2EE (JSF + Hibernate) PDF
ndice
1. Introduccin.................................................................................................2
Referencias ................................................................................................... 20
-1-
1. Introduccin.
El modelo est representado por las clases generadas con Hibernate: clases
base que representarn las tablas de la base de datos y clases gestoras que se
encargarn de manejar dichos datos.
La vista la componen todos los ficheros JSP, CSS, HTML, Javascript, que
se encargarn de reproducir el resultado de las acciones realizadas.
Tambin son usadas otras tecnologas como HTML, CSS y Javascript para
aadir ms funcionalidad a la parte visual de la aplicacin, pero que en este
manual no se explicar.
Todos los proyectos hacen uso, como mnimo, de los dos framework
anteriormente mencionados, Hibernate y JSF, y del servidor Tomcat
(recomendado). La explicacin del desarrollo de este proyecto tambin es
vlida para el servidor Glassfish 2 ya que no necesita ninguna configuracin
adicional.
-2-
2.1. Seleccin del tipo de proyecto: Java Web, Web Application
-3-
2.3.a. Seleccin del servidor: Tomcat / Glassfish 2
2.3.b. Seleccin de la versin J2EE: Java EE 5
2.4. Seleccin de los frameworks: Hibernate y JSF (dejar todo por defecto).
-4-
3. Estructura del proyecto. Ficheros y directorios.
Una vez planificado cual ser nuestro modelo, nuestro proyecto de ejemplo
quedar as:
-5-
4. Librera c3p0.
Para aplicaciones web de larga vida con conexiones a base de datos existe el
gran inconveniente de que MySQL finaliza por defecto todas las conexiones
despus de las 8 horas de inactividad.
c3p0 es una librera de fcil uso que aumenta la funcionalidad de los drivers
JDBC para las conexiones de las aplicaciones con base de datos.
4.2. Se incluye los ficheros JAR de la librera en el proyecto. Botn Add JAR/Folder.
-6-
5. Configuracin de la base de datos.
<mapping resource="ddbb.hbm.xml"/>
</session-factory>
</hibernate-configuration>
-7-
6. Esquema de la base de datos.
En las clases del modelo se indican los atributos y los mtodos GETTER y
SETTER de cada uno de ellos. Opcionalmente, se pueden aadir otros.
Tambin se recomienda el uso de valor numrico para los valores booleans por
problemas de conversin.
Register.java
package database.entity;
import java.sql.Timestamp;
public Register(){
name = "";
currentTime = new Timestamp(System.currentTimeMillis());
price = new Double(0);
enabled = 0;
}
-8-
public Double getPrice() {
return price;
}
En este fichero se indican todas las clases del modelo junto con sus atributos y
relaciones con otras clases del modelo.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="database.entity.Register" table="register">
<id column="register_id" name="id">
<generator class="identity"/>
</id>
<property name="name" />
<property name="currentTime" column="time_current" />
<property name="price"/>
<property name="enabled" />
</class>
</hibernate-mapping>
-9-
7.1.a. Se indica un nuevo archivo en el paquete database.common.
7.1.b. Se selecciona Hibernate, HibernateUtil.java
HibernateUtil.java
package database.common;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
- 10 -
7.2. Creamos una clase con funcionalidades adicionales.
Util.java
package database.common;
7.4. Se disea la clase gestora con las funcionalidades comunes: crear, actualizar,
borrar, listar, ...
HibernateManager.java
package database.common;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
- 11 -
/**
* Obtener un elemento a partir de su identificador
* Se supone que en todas las entidades existe el atributo id que las identifica
* @param id
* @return
*/
public Object getElementById(Long id){
Object obj = new Object();
// obtener la sesion actual
Session session = getSession();
try {
// comenzar la transaccion
session.beginTransaction();
// cargar objeto por clave
obj = session.createCriteria(myClass.getClass()).add(Restrictions.eq("id",
id)).uniqueResult();
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en getElementById: " + e);
// deshacer transaccion
this.rollback();
}
return obj;
}
/**
* Guardar un objeto en la base de datos
* @param o
*/
public boolean create(Object o) {
// obtener la sesion actual
Session session = getSession();
try {
// comenzar la transaccion
session.beginTransaction();
// almacenarlo
session.save(o);
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en create: " + e);
// deshacer transaccion
this.rollback();
return false;
}
return true;
}
/**
* Actualizar un objeto en la base de datos
* @param o
*/
public boolean update(Object o){
// obtener la sesion actual
Session session = getSession();
try {
// comenzar la transaccion
session.beginTransaction();
// actualizarlo
session.saveOrUpdate(o);
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en update: " + e);
// deshacer transaccion
this.rollback();
return false;
}
return true;
}
- 12 -
/**
* Borrar un objeto de la base de datos
* @param o
*/
public boolean delete(Object o) {
if(o == null){
return false;
}
// obtener la sesion actual
Session session = getSession();
try {
// comenzar la transaccion
session.beginTransaction();
// borrarlo
session.delete(o);
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en delete: " + e);
// deshacer transaccion
this.rollback();
return false;
}
return true;
}
/**
* Obtener la lista de registros para una entidad
* @return
*/
public List getList(){
// obtener la sesion actual
Session session = getSession();
List result = new ArrayList();
try {
// comenzar la transaccion
session.beginTransaction();
// obtener la lista de eventos
result = session.createCriteria(myClass.getClass()).list();
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en getList: " + e);
// deshacer transaccion
this.rollback();
}
return result;
}
/**
* Obtener una lista de registros de una entidad limitada
* @param ini Indice inicial
* @param batch Cantidad de registros a obtener
* @return
*/
public List getSubList(int ini, int batch){
// obtener la sesion actual
Session session = getSession();
List result = new ArrayList();
try {
// comenzar la transaccion
session.beginTransaction();
// obtener la lista de eventos
List aux = session.createCriteria(myClass.getClass()).list();
for(int i = ini; i < aux.size() && i < ini + batch; i++){
result.add(aux.get(i));
}
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en getSubList: " + e);
// deshacer transaccion
this.rollback();
}
return result;
}
- 13 -
/**
* Cantidad de registros de una entidad
* @return
*/
public int getListCount() {
Number count = 0;
// obtener la sesion actual
Session session = getSession();
try {
// comenzar la transaccion
session.beginTransaction();
// obtener la cantidad
count = (Number)
session.createCriteria(myClass.getClass()).setProjection(Projections.rowCount()).uniqueRes
ult();
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en getListCount: " + e);
// deshacer transaccion
this.rollback();
}
return count.intValue();
}
/**
* Comprobar si esta repetido un objeto a partir de un valor de un atributo
* @param attr
* @param value
* @return
*/
public boolean checkRepeated(String attr, String value){
Object obj = new Object();
// obtener la sesion actual
Session session = getSession();
try {
// comenzar la transaccion
session.beginTransaction();
// cargar objeto por clave
obj = session.createCriteria(myClass.getClass()).add(Restrictions.eq(attr,
value)).uniqueResult();
// confirmar transaccion
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error en checkRepeated: " + e);
// deshacer transaccion
this.rollback();
}
return obj != null ? true : false;
}
/**
* Obtener la sesion de hibernate para el acceso a la base de datos
* @return
*/
protected Session getSession(){
Session session = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
if(!session.isOpen()){
session = HibernateUtil.getSessionFactory().openSession();
}
} catch(Exception e){
session = HibernateUtil.getSessionFactory().openSession();
}
return session;
}
/**
* Obtener el nombre de la tabla al que hace referencia
* @return
*/
public String getTableName(){
return TABLE;
}
- 14 -
/**
* Hacer rollback y que no se termine la aplicacion tras un fallo
*/
public void rollback(){
Session session = getSession();
try {
// deshacer transaccion
session.getTransaction().rollback();
} catch (Exception e) {
System.out.println("Error en rollback: " + e);
}
}
}
7.5. Para cada clase del modelo se disea otra en el paquete database.manager
que heredar de HibernateManager y que se encargar de gestionar dicha clase
del modelo indicando solamente el nombre de la tabla y la clase del modelo.
RegisterManager.java
package database.manager;
import database.common.HibernateManager;
import database.entity.Register;
public RegisterManager(){
TABLE = "register";
myClass = new Register();
}
}
Por tanto, los objetos que se referencien en la parte de la vista tendrn sus
mtodos GETTER y SETTER. Estos son: los objetos de clases del modelo, los
objetos de listado (DataModel) y todos aqullos que se incorporen como
auxiliares.
- 15 -
WebManagedBean.java
package web;
import database.entity.Register;
import database.manager.RegisterManager;
import java.util.ArrayList;
import java.util.List;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
public WebManagedBean() {
}
- 16 -
public String gotoIndex(){
refreshListRegister();
// limpiar informacion
register = new Register();
value = new Integer(0);
return "index";
}
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>WebManagedBean</managed-bean-name>
<managed-bean-class>web.WebManagedBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>update</from-outcome>
<to-view-id>/update.jsp</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>
- 17 -
10. Parte visual.
En la parte visual, para hacer uso de las etiquetas del framework JSF se aade
previamente a su uso las siguientes lneas, indicando las libreras:
Para hacer uso de un mtodo SETTER del Managed Bean se invoca al mtodo
quitando el prefijo set:
<h:inputText value="#{WebManagedBean.register.name}" />
header.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Proyecto</title>
</head>
<body>
footer.jsp
</body>
</html>
- 18 -
index.jsp
<jsp:include page="includes/header.jsp" />
<f:view>
<h:form>
<h2>Nuevo registro</h2>
<table>
<tr>
<td>Nombre:</td>
<td><h:inputText value="#{WebManagedBean.register.name}" /></td>
</tr>
<tr>
<td>Precio:</td>
<td><h:inputText value="#{WebManagedBean.register.price}" /></td>
</tr>
<tr>
<td>Activar:</td>
<td>
<h:selectOneMenu value="#{WebManagedBean.value}">
<f:selectItems value="#{WebManagedBean.availableOptions}"/>
</h:selectOneMenu>
</td>
</tr>
<tr>
<td></td>
<td>
<h:commandButton action="#{WebManagedBean.newRegister}"
value="Crear"/>
</td>
</tr>
</table>
<h2>Listado</h2>
<h:dataTable value='#{WebManagedBean.data}' var='dataTableItem'>
<h:column>
<f:facet name="header">
<h:outputText value="Nombre"/>
</f:facet>
<h:outputText value="#{dataTableItem.name}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Fecha"/>
</f:facet>
<h:outputText value="#{dataTableItem.currentTime}">
<f:convertDateTime pattern="dd/MM/yyyy HH:mm aaa" />
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Precio"/>
</f:facet>
<h:outputText value="#{dataTableItem.price}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Activo"/>
</f:facet>
<h:outputText rendered="#{dataTableItem.enabled == 0}"
value="Deshabilitado"/>
<h:outputText rendered="#{dataTableItem.enabled == 1}"
value="Habilitado"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Actualizar"/>
</f:facet>
<h:commandButton action="#{WebManagedBean.gotoUpdate}" value="A"/>
</h:column>
- 19 -
<h:column>
<f:facet name="header">
<h:outputText value="Borrar"/>
</f:facet>
<h:commandButton action="#{WebManagedBean.deleteRegister}" value="X"/>
</h:column>
</h:dataTable>
</h:form>
</f:view>
Update.jsp
<f:view>
<h:form>
<table>
<tr>
<td>Nombre:</td>
<td><h:outputText value="#{WebManagedBean.register.name}" /></td>
</tr>
<tr>
<td>Precio:</td>
<td><h:inputText value="#{WebManagedBean.register.price}" /></td>
</tr>
<tr>
<td>Activar:</td>
<td>
<h:selectOneMenu value="#{WebManagedBean.value}">
<f:selectItems value="#{WebManagedBean.availableOptions}"/>
</h:selectOneMenu>
</td>
</tr>
<tr>
<td></td>
<td>
<h:commandButton action="#{WebManagedBean.updateRegister}"
value="Actualizar"/>
</td>
</tr>
</table>
<h:commandButton action="#{WebManagedBean.gotoIndex}" value="Volver"/>
</h:form>
</f:view>
Referencias
- 20 -