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.

package com.ezjamvc.modelo.facade;

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.

package com.ezjamvc.modelo.delegate;

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.

package com.ezjamvc.vista.formularios;
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:

  1. Data Transfers object
  2. Data Access object
  3. Session Facade
  4. Bussines Delegate

Despues crearemos la interfaz grafica, pero eso sera en una semana mas o menos

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

finally

No deberías tener un finally siempre donde cierras la conexión, siempre que usas una conexión JDBC directamente?

Connection conn = null;
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.

Imagen de domix

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

Imagen de jasuncionez

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

finally {
            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.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("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

20/05/2010 06:01:20 PM PruebaDelegate main
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.

GRAVE: null
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,

Yo me ejecuto en el finally
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

private void cerrar(PreparedStatement ps) throws SQLException {
        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

run:
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!!

Imagen de benek

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.