Aplicacion Con Acceso a Bases de Datos Java MySql y Patrones de Diseño Parte 4
Ahora continuando con el proyecto se crearan las clases correspondientes al patron facade y delegate, iniaremos con la clase ArticuloFacade del paquete facade. Para mas información ir a Session Facade .
Creación de la clase ArticuloFacade
1. Seleccionar el paquete com.ezjamvc.modelo.facade
2. Clic secundario
3. Nuevo
4. Clase java
Por lo tanto la codificación de la clase quedaria de la siguiente forma.
import com.ezjamvc.modelo.dao.ArticuloDAO;
import com.ezjamvc.modelo.dto.ArticuloDTO;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/** @author asuncion */
public class ArticuloFacade {
private Connection cnn;
private ArticuloDAO dao;
public ArticuloFacade(Connection cnn) {
this.cnn = cnn;
dao = new ArticuloDAO();
}
public void crear(ArticuloDTO dto) throws SQLException {
dao.create(dto, cnn);
}
public List listar() throws SQLException {
return dao.loadAll(cnn);
}
public ArticuloDTO leer(ArticuloDTO dto)throws SQLException {
return dao.load(dto, cnn);
}
public void actualiza(ArticuloDTO dto)throws SQLException {
dao.update(dto, cnn);
}
public void elimina(ArticuloDTO dto)throws SQLException {
dao.delete(dto, cnn);
}
}
Lo interesante de esta clase es que el constructor recibe como parametro la conexion a la base de datos.
Ahora se crearan la clase correspondiente al patron delegate, la clase EzjaMVCDelegate del paquete delegate, es la ruta de entrada a la aplicación, es la clase que agrupara las acciones para cada uno d elos modulos de la aplicación. Para mas información ir a Business Delegate.
Creación de la clase EzjaMVCDelegate
1. Seleccionar el paquete com.ezjamvc.modelo.delegate
2. Clic secundario
3. Nuevo
4. Clase java
Por lo tanto la codificación de la clase quedaria de la siguiente forma.
import com.ezjamvc.modelo.dto.ArticuloDTO;
import com.ezjamvc.modelo.facade.ArticuloFacade;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
/**
*
* @author asuncion
*/
public class EzjaMVCDelegate {
private Connection cnn;
private ArticuloFacade artFacade;
public EzjaMVCDelegate() {
String user = "root";
String pwd = "admin";
String url = "jdbc:mysql://localhost:3306/EzjaMVC";
String mySqlDriver = "com.mysql.jdbc.Driver";
try {
Class.forName(mySqlDriver);
cnn = DriverManager.getConnection(url, user, pwd);
} catch (Exception e) {
e.printStackTrace();
}
artFacade = new ArticuloFacade(cnn);
}
//Codigo para los Articulos
public void crearArticulo(ArticuloDTO dto) throws SQLException {
artFacade.crear(dto);
}
public List listarArticulos() throws SQLException {
return artFacade.listar();
}
public ArticuloDTO leerArticulo(ArticuloDTO dto) throws SQLException {
return artFacade.leer(dto);
}
public void actualiza(ArticuloDTO dto) throws SQLException {
artFacade.actualiza(dto);
}
public void elimina(ArticuloDTO dto) throws SQLException {
artFacade.elimina(dto);
}
}
Al revisar el codigo, nos podemos dar cuenta que al momento de definir el constructor, se obtiene una conexion a la base de datos, la cual se pasa como parametro a la instancia de ArticuloFacade que se crea.
Cabe mencionar que la estructura final de la aplicacion es la siguiente.
Ahora modificaremos ligeramente la clase de prueba para verificar el funcionamiento de la aplicacion.
import com.ezjamvc.modelo.delegate.EzjaMVCDelegate;
import com.ezjamvc.modelo.dto.ArticuloDTO;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/** @author asuncion */
public class PruebaDelegate {
public PruebaDelegate() {
}
public static void main(String[] args) {
EzjaMVCDelegate del = new EzjaMVCDelegate();
ArticuloDTO dto = new ArticuloDTO();
try {
//Agregar un registro nuevo
//dto.setClaveArticulo("art1000");
//dto.setDescripcion("libreta");
//dto.setExistencias(100);
//dto.setPrecio(5000);
//del.crearArticulo(dto);
//Actualizar un registro existente
//dto.setClaveArticulo("art1000");
//dto.setDescripcion("lap hp ");
//dto.setExistencias(100);
//dto.setPrecio(5000);
// del.actualiza(dto);
//Eliminar un registro
//dto.setClaveArticulo("art1000");
//del.elimina(dto);
//Mostrar un solo registro
//dto.setClaveArticulo("art1000");
//dto = del.leerArticulo(dto);
//System.out.println(dto);
//Listar los registros
System.out.println(del.listarArticulos());
} catch (SQLException ex) {
Logger.getLogger(PruebaDelegate.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Y con esto terminamos con todas las capas del modelo de la aplicacion propuesta. En la cual se aplican los 4 patrones antes mencionados:
- Data Transfers object
- Data Access object
- Session Facade
- Bussines Delegate
Despues crearemos la interfaz grafica, pero eso sera en una semana mas o menos
- jasuncionez's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
finally
No deberías tener un finally siempre donde cierras la conexión, siempre que usas una conexión JDBC directamente?
try {
conn = obtenerUnaConexionComoSea();
//usar la conexion
} catch (SQLException ex) {
//manejar el error
} finally {
if (conn != null) {
conn.close();
}
}
De este modo, aunque se interrumpa el código porque se arroja otra excepción que no tienes contemplada (alguna de tiempo de ejecución, como NullPointerException, IllegalStateException, OutOfMemoryError, etc) el segmento dentro del
finally
se ejecutará para cerrar esa conexión.Como
Como comentario:
Felicidades, esta bien tu esfuerzo, veo que tienes buena implementación de los patrones, pero tienes en código duro los parámetros de conexión, tal vez no era tu intención meterte con esas cosas.
Saludos
finally
Estoy de acuerdo en parte de que la conexion y todos los recursos deben ser liberados con un bloque finally, de echo con algo como esto, en la clase EzjaMVCDelegate
if (cnn != null) {
try {
cnn.close();
} catch (SQLException ex) {
Logger.getLogger(EzjaMVCDelegate.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Ahora bien no hay que olvidar que el finally se ejecuta siempre funcione o no funcione lo que este en el try
ahora si probamos la aplicacion despues de haberle agregado el bloque finnally que usted propone
import com.ezjamvc.modelo.dto.ArticuloDTO;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/** @author asuncion */
public class PruebaDelegate {
public PruebaDelegate() {
}
public static void main(String[] args) {
EzjaMVCDelegate del = new EzjaMVCDelegate();
ArticuloDTO dto = new ArticuloDTO();
try {
//Agregar un registro nuevo
dto.setClaveArticulo("art10000");
dto.setDescripcion("libreta");
dto.setExistencias(100);
dto.setPrecio(5000);
del.crearArticulo(dto);
} catch (SQLException ex) {
Logger.getLogger(PruebaDelegate.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Se tendrá este resultado
GRAVE: null
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
ahora si quitamos el fragmento finally que propone generamos un error de duplicidad de llave primaria a proposito por ejemplo art02 que ya existe se obtiene lo siguiente.
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'art02' for key 1
y siempre la conexion y demas recursos son liberados ya que asi lo indican cada uno de los metodos en la clase ArticuloDAO, por ejemplo la salida agregando un simple mensaje que indica lo que esta haciendo en los metodos close de la clase Articulo DAO que son llamados en el finally de todos los metodos CRUD, generando el error anterior seria el siguiente,
Y cierro el PreparedStatement
Yo me ejecuto en el finally
Y cierro la conexion
20/05/2010 06:09:32 PM PruebaDelegate main
GRAVE: null
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'art02' for key 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
e insisto todos los recursos son liberados en ArticuloDAO en los metodos close
if (ps != null) {
try {
ps.close();
System.out.println("Yo me ejecuto en el finally");
System.out.println("Y cierro el PreparedStatement");
} catch (SQLException e) {
}
}
}
private void cerrar(Connection cnn) {
if (cnn != null) {
try {
cnn.close();
System.out.println("Yo me ejecuto en el finally");
System.out.println("Y cierro la conexion");
} catch (SQLException e) {
}
}
}
Y si probamos agregando un registro que no existe en la tabla se obtiene una salida como esta
Yo me ejecuto en el finally
Y cierro el PreparedStatement
Yo me ejecuto en el finally
Y cierro la conexion
GENERACIÓN CORRECTA (total time: 1 second)
Por lo que garantizamos que siempre se cerraran todos los recursos exista o no error alguno
Buena info
Buen tutorial
MUY BUEN TUTORIAL
TENGO UNA DUDA ESTE EJEMPLO LO PUEDO UTILIZAR PARA EXPLICAR EL MODELO-VISTA-CONTROLADOR Y SI ES ASÍ CUAL CLASE ES EL MODELO, QUE CLASE ES EL CONTROLADOR Y QUE CLASE ES LA VISTA Y SI NO ES MUCHA MOLESTIA DONDE PUEDO ENCONTRAR LA INTERFACE GRÁFICA GRACIAS!!
Re: MUY BUEN TUTORIAL
Quizá no sea el ejemplo adecuado para exponer el patrón MVC, porque esta serie de artículos de jasuncionez expone y explica varios patrones (DTO, Facade, Business-Delegate) y eso podría confundirte.
MVC está a nivel conceptual, puedes explicarlo sin necesidad de mostrar código, porque no está pegado a ningún framework, los frameworks son los que implementan esa "idea", pero si necesitas ejemplos en mi opinión uno de los frameworks que mejor exponen el concepto es Spring MVC. En otros frameworks el "controller" solamente se configura vía XML, pero en Spring MVC sí se desarrolla un controller para cada petición. Esto te puede servir.
En esta presentación tengo un par de slides sobre MVC que quizá te puedan servir.
Saludos.