Mostrando entradas con la etiqueta Patrones. Mostrar todas las entradas
Mostrando entradas con la etiqueta Patrones. Mostrar todas las entradas

Java Web Lección 03: Patrón MVC

JAVA WEB - LECCIÓN 02: PATRON MVC

INTRODUCCIÓN

El Patrón Model-View-Controller (MVC) es el mas utilizado en desarrollo web.

Este patrón permite estructurar una aplicación web en tres capas, donde cada una tiene una responsabilidad bien definida, haciendo mas fácil el desarrollo y mantenimiento de la aplicación.



DIAPOSITIVA

CÓDIGO FUENTE - EUREKA-WEB-ORACLE-JDBC

En esta oportunidad te presento un video donde te explico cómo ejecutar el código fuente de una aplicación Java Web, utilizando HTML, CSS, JavaScript, AJAX y JSON, en la capa de persistencia se utiliza JDBC y base de datos Oracle XE 11g.

Tú tienes acceso al código fuente de esta aplicación, después del video esta el enlace.



Java Web Lección 03: Patrón MVC

SQL SERVER ORACLE MYSQL JAVA JAVAEE JDBC MVC DAO PATRONES ANDROID SERVLETS JSP WEB JAVA WEB SERVLETS JSP MVC DAO EJB JDBC

INTRODUCCIÓN

El Patrón Model-View-Controller (MVC) es el mas utilizado en desarrollo web.

Este patrón permite estructurar una aplicación web en tres capas, donde cada una tiene una responsabilidad bien definida, haciendo mas fácil el desarrollo y mantenimiento de la aplicación.



DIAPOSITIVA



TALLER VIRTUAL DE SPRING FRAMEWORK

Acceso a Cursos Virtuales

Java Web Lección 03: Patrón MVC

SQL SERVER ORACLE MYSQL JAVA JAVAEE JDBC MVC DAO PATRONES ANDROID SERVLETS JSP WEB JAVA WEB SERVLETS JSP MVC DAO EJB JDBC

INTRODUCCIÓN

El Patrón Model-View-Controller (MVC) es el mas utilizado en desarrollo web.

Este patrón permite estructurar una aplicación web en tres capas, donde cada una tiene una responsabilidad bien definida, haciendo mas fácil el desarrollo y mantenimiento de la aplicación.



DIAPOSITIVA

CÓDIGO FUENTE - EUREKA-WEB-ORACLE-JDBC

En esta oportunidad te presento un video donde te explico cómo ejecutar el código fuente de una aplicación Java Web, utilizando HTML, CSS, JavaScript, AJAX y JSON, en la capa de persistencia se utiliza JDBC y base de datos Oracle XE 11g.

Tú tienes acceso al código fuente de esta aplicación, después del video esta el enlace.



Java Web Lección 03: Patrón MVC

SQL SERVER ORACLE MYSQL JAVA JAVAEE JDBC MVC DAO PATRONES ANDROID SERVLETS JSP WEB JAVA WEB SERVLETS JSP MVC DAO EJB JDBC

INTRODUCCIÓN

El Patrón Model-View-Controller (MVC) es el mas utilizado en desarrollo web.

Este patrón permite estructurar una aplicación web en tres capas, donde cada una tiene una responsabilidad bien definida, haciendo mas fácil el desarrollo y mantenimiento de la aplicación.



DIAPOSITIVA



TALLER VIRTUAL DE SPRING FRAMEWORK

Acceso a Cursos Virtuales

JAVA WEB - COMBOS ANIDADOS CON JQUERY Y JSON

JAVA WEB - COMBOS ANIDADOS CON JQUERY Y JSON
INTRODUCCIÓN
Cuando desarrollamos una aplicación web, una de las tareas mas frecuentes que tenemos que programar son los combos anidados, el ejemplo tipico es el del código de ubicación geografica (UBIGEO).
En este oportunidad desarrollare un ejemplo utilizando la base de datos EurekaBank y la plataforma Java.
La base de datos la puede descargar desde:
FUNDAMENTOS
JSON
JSon es una notación para representar arreglos y objetos JavaScript, se puede encontrar mas información en la siguiente URL:
GSON
Gson es una librería de Java que se puede utilizar para convertir objetos Java en su representación JSON. Podemos encontrar mas información en la siguiente dirección:
Por ejemplo, para convertir un Map con diferentes tipos de objetos las sentencias son las siguientes:
Map<String, Object> rpta = new HashMap<String, Object>();
EurekaModel model = new EurekaModel();
List<Map<String, ?>> lista = model.consultarCuentas("001");
rpta.put("rpta", "1");
rpta.put("lista", lista);
Gson gson = new Gson();
String texto = gson.toJson(rpta);
System.out.println(texto);
El resultado que se obtiene es el siguiente:
{"lista":[{"descripcion":"Cuenta: 00100001 | Moneda: 01 | Saldo: 6900.0","cuenta":"00100001"},{"descripcion":"Cuenta: 00100002 | Moneda: 02 | Saldo: 4500.0","cuenta":"00100002"}],"rpta":"1"}
EL CASO
DESCRIPCIÓN
De lo que se trata es de llenar el combo de cuentas en función al valor que el usuario seleccione en el combo de sucursales, tal como se muestra en la siguiente imagen:
SUCURSALES
Mediante un listener de sesión cargamos la lista de sucursales en sesión, la clase es la siguiente:
package pe.egcc.demo.servlets;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import pe.egcc.demo.model.EurekaModel;

/**
 *
 * @author Eric Gustavo Coronel Castillo
 * @blog gcoronelc.blogspot.com
 */
@WebListener()
public class SessionListener implements HttpSessionListener {

  @Override
  public void sessionCreated(HttpSessionEvent event) {
    try {
      EurekaModel model = new EurekaModel();
      event.getSession().setAttribute("sucursales", model.cosultarSucursales());
    } catch (Exception e) {
    }
  }

  @Override
  public void sessionDestroyed(HttpSessionEvent event) {
  }
}
Luego para llenar el combo utilizamos JSTL, el script es el siguiente:
<label>Sucursal</label><br/>
<select id="cboSucursal">
<option value="000">[Seleccione sucursal]</option>
<c:forEach items="${sessionScope.sucursales}" var="rec">
  <option value="${rec.codigo}">${rec}</option>
</c:forEach>
</select><br/>
<label>Cuenta</label><br/>
<select id="cboCuenta">
</select><br/>
CUENTAS
Para llenar el combo de cuentas se utiliza un servlet que retorna el resultado como un objeto JSon, se utiliza la librería GSON. La clase es la siguiente:
package pe.egcc.demo.servlets;

import com.google.gson.Gson;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pe.egcc.demo.model.EurekaModel;

/**
 *
 * @author Eric Gustavo Coronel Castillo
 * @blog gcoronelc.blogspot.com
 */
@WebServlet(name = "DemoController", urlPatterns = {"/TraerCuentas"})
public class DemoController extends HttpServlet {

  private static final long serialVersionUID = 1L;

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    PrintWriter out = response.getWriter();
    Map<String, Object> rpta = new HashMap<String, Object>();
    try {
      // La siguiente línea es para poder apreciar el efecto AJAX.
      Thread.currentThread().sleep(2000);
      // Dato
      String sucursal = request.getParameter("sucursal");
      // Proceso
      EurekaModel model = new EurekaModel();
      List<Map<String, ?>> lista = model.consultarCuentas(sucursal);
      rpta.put("rpta", "1");
      rpta.put("lista", lista);
    } catch (Exception e) {
      rpta.put("rpta", "-1");
      rpta.put("mensaje", e.getMessage());
    }
    Gson gson = new Gson();
    out.print(gson.toJson(rpta));
    out.flush();
    out.close();
  }

}
Luego, para llenar el combo utilizamos JQuery, el script es el siguiente:
<script type="text/javascript" src="jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
$("#cboSucursal").change(function() {
  var cboCuenta = $("#cboCuenta");
  cboCuenta.empty();
  var sucursal = $("#cboSucursal").val();
  if (sucursal == '000') {
 return;
  }
  var data = "sucursal=" + sucursal;
  cboCuenta.append('<option value="">Cargando...</option>').val('');
  $.post("TraerCuentas", data, function(objJson) {
 cboCuenta.empty();
 if (objJson.rpta == -1) {
   alert(objJson.mensaje);
   return;
 }
 var lista = objJson.lista;
 if(lista.length > 0){
   cboCuenta.append("<option value='0'>[Seleccione cuenta]</option>");
 } else {
   cboCuenta.append("<option value='0'>[No hay cuentas]</option>");
 }
 for (var i = 0; i < lista.length; i++) {
   var item = "<option value='" + lista[i].cuenta + "'>" + lista[i].descripcion + "</option>";
   cboCuenta.append(item);
 }
  });
});
$("#cboCuenta").change(function() {
  var cuenta = $("#cboCuenta").val();
  if(cuenta=="0"){
 return;
  }
  alert("Cuenta: " + cuenta);
});
</script>
PROYECTO COMPLETO
Puede descargar el proyecto completo desde el siguiente enlace:
CÓDIGO FUENTE
En esta sección te presento un video que una aplicación CLIENTE-SERVIDOR desarrollada con Java y Oracle.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.



Java OO - Lección 08 - Colecciones

Cliente-Servidor, DAO, Eclipse, GlassFish, Java, Java POO, JAVA SERVER FACES, Java Web, JEE, JFreeChart, Patrones, POO, Tomcat, Web, Colecciones
JAVA POO - LECCION 08 - COLECCIONES

INTRODUCCIÓN

Las colecciones son un conjunto de interfaces, clases abstractas y clases concretas que te permiten manejar una gran cantidad de datos relacionados en forma de listas para lo cual dispones de la interfaz List y la clase ArrayList, también como pares de datos CLAVE->VALOR para los cual dispones de la interfaz Map y la clase HashMap.
Todas las clases que nos permiten manejas conjuntos de datos se agrupan en un marco de trabajo conocido como Java Colecction Framework (JCF), y entre sus características la que mas resalta es que soporte Generics, esto quiere decir que podemos crear por ejemplo lista genéricas de tipo Object o listas personalizadas, por ejemplo de tipo Producto, Cliente, Cuenta, etc.
Una de sus aplicación la tenemos en la capa DAO, por ejemplo, si estamos consultan los productos de una categoría, la capa DAO estaría retornando una lista con objetos de tipo Producto.
Todos los componentes de JCF se encuentran en el paquete java.util.

DIAPOSITIVA

PRESENTACIÓN DEL TEMA

CURSO PROFESIONAL DE JAVA ORIENTADO A OBJETOS

En esta sección te presento el curso virtual de JAVA ORIENTADO A OBJETOS.

CODIGO FUENTE - EUREKA-WEB-MYSQL-SPRING

En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.



Java Web Lección 01: Servlets

JAVA WEB - LECCIÓN 01: SERVLETS

INTRODUCCIÓN

El servlet es la tecnología Java que permite crear aplicaciones web dinámicas, es decir, que permite al usuario interactuar con la aplicación, por ejemplo, hacer consultas, insertar y eliminar datos, etc.

Un Servlet es un objeto java que pertenece a una clase que extiende de javax.servlet.http.HttpServlet, y admite peticiones a través del protocolo HTTP. El servlet recibe peticiones desde un navegador web, las procesan y devuelven una respuesta al navegador, normalmente en HTML.

Para obtener la respuesta que debe enviar, un servlet puede acceder a bases de datos, comunicarse con otros componente, como por ejemplo, un Bean, un EJB, o tal vez un Web Service.

En esta lección veremos cómo crear e interactuar con los servlets.

DIAPOSITIVA

CÓDIGO FUENTE - EUREKA-WEB-ORACLE-JDBC

En esta oportunidad te presento un video donde te explico cómo ejecutar el código fuente de una aplicación Java Web, utilizando HTML, CSS, JavaScript, AJAX y JSON, en la capa de persistencia se utiliza JDBC y base de datos Oracle XE 11g.

Tú tienes acceso al código fuente de esta aplicación, después del video esta el enlace.

CÓDIGO FUENTE - EUREKA-WEB-MYSQL-SPRING

En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.

Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.



JAVA SERVER FACES
LECCION 01- PRIMEROS PASOS

JAVA SERVER FACES, Eclipse, GlassFish, Java, Java Web, JEE, Patrones, Web

INTRODUCCIÓN

En esta primera sesión entenderemos la arquitectura de JSF, crearemos nuestros primeros ejemplos, y también accederemos a una base de datos utilizando JDBC.

DIAPOSITIVA

CÓDIGO FUENTE - EUREKA-CS-ORACLE-JDBC
En esta sección te presento un video de una aplicación CLIENTE-SERVIDOR.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.
CÓDIGO FUENTE - EUREKA-WEB-ORACLE-JDBC
En esta oportunidad te presento un video donde te explico cómo ejecutar el código fuente de una aplicación Java Web, utilizando HTML, CSS, JavaScript, AJAX y JSON, en la capa de persistencia se utiliza JDBC y base de datos Oracle XE 11g.
Tú tienes acceso al código fuente de esta aplicación, después del video esta el enlace.
CÓDIGO FUENTE - EUREKA-WEB-MYSQL-SPRING
En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.


Resumen Seminario Java Cliente-Servidor

SEMINARIO CLIENTE - SERVIDOR CON JAVA
PARTE I - CONOCIENDO AL MONSTRUO
Cliente-Servidor: Aclarando Conceptos
Cliente-Servidor
Es un modelo basado en la cooperación e interacción de dos partes conocidas como servidor o back-end y cliente o front-end.
Aplicación Servidor
Es la aplicación que provee servicios, es la aplicación que provee los servicios; por ejemplo, los servidores de base de datos ofrecen servicios de persistencia de datos, podríamos mencionar a SQL Server, Oracle, MySQL, etc,
Aplicación Cliente
Es la aplicación que hace uso o consume los servicios de la Aplicación Servidor; por ejemplo, las aplicaciones comerciales como los sistemas de ventas y compras necesitan que sus datos persistan en el tiempo, para lo cual se recurren a los servidores de base de datos que ofrecen estos servicios.
Arquitectura Cliente-Servidor
El cliente se encuentra del lado del usuario y se define como un proceso consumidor de servicios, mientras que el servidor provee los servicios requeridos y se encuentra de manera remota al usuario y es transparente al cliente.
Los clientes deben estar en la red de la empresa, estas pueden ser redes locales, pero también es posible tener clientes remotos a través por ejemplo de una red VPN.
El API JDBC: Implementaciones
API JDBC
Esta API está compuesta por un conjunto de clases e interfaces que estandarizan el acceso a las bases de datos. Gracias a la utilización de JDBC, un programa Java puede acceder a cualquier base de datos sin necesidad de modificar la aplicación. Sin embargo, para que esto sea posible es necesario que el fabricante ofrezca un driver que cumpla la especificación JDBC.
Tipos de Driver
Tenemos cuatro tipos de driver:
  • Tipo 1: JDBC-ODBC bridge driver
  • Tipo 2: Native API/Partly Java Driver
  • Tipo 3: Pure Java Driver
  • Tipo 4: Native Protocol Java Driver
Tipo 1: JDBC-ODBC bridge driver
Permite utilizar drivers ODBC, su desventaja es que se debe instalar el driver ODBC en cada cliente.
Tipo 2: Native API/Partly Java Driver
Requiere que se instalen las librerías nativas en cada cliente.
Tipo 3: Pure Java Driver
Este tipo de driver traduce llamadas JDBC en un protocolo de red independiente del DBMS y luego, a un protocolo de DBMS.
Un Servidor JDBC, realiza la tarea de middleware, siendo capaz de conectar un cliente Java a diferentes bases de datos.
Tipo 4: Native Protocol Java Driver
El driver tipo 4 convierte llamadas JDBC directamente en el protocolo de red usado por el DBMS. Esto permite llamadas directas desde la máquina del cliente al servidor del DBMS, es una solución muy práctica y la más utilizada.
El API JDBC: Componentes Principales
Objeto: Connection
Establece la conexión con la base de datos y maneja las transacciones.
Objeto: Statement
Se utiliza para ejecutar sentencias sin parámetros.
Objeto: PreparedStatement
Se utiliza para ejecutar sentencias con parámetros.
Objeto: CallableStatement
Se utiliza para ejecutar procedimientos almacenados.
Objeto ResultSet
Se utiliza para procesar resultados.
Estrategias para programar transacciones
Controladas desde el cliente
En este caso desde la aplicación java programamos el inicio y fin de la transacción.
Controladas en la base de datos
En este caso programamos la transacción en el procedimiento almacenado.
El patrón DAO
Desarrollo Clásico
En el objeto de negocio se programa la lógica de negocio y la lógica de persistencia, haciendo difícil su mantenimiento.
Patrón DAO – División en Capas
El patrón DAO permite dividir en capas separadas la lógica de negocio y la lógica de persistencia.
Patrón DAO – Estructura
La capa de negocio hace uso de la capa de persistencia, y para que se comuniquen los datos se utilizan objetos Transfer Object (TO), también denominados Data Transfer Object (DTO).
Por ejemplo, si se consulta los datos de un cliente, el objeto DAO devolverá un objeto TO con los datos del cliente. Si se consulta los artículos de una categoría, el objeto DAO devolverá una colección de objetos TO de tipo Artículo.
Patrón DAO – Diagrama se secuencia
En el diagrama de secuencia se puede apreciar la responsabilidad de cada capa, la capa Data Source puede ser un motor de base de datos, como por ejemplo Oracle, MySQL o SQL Server.
PARTE II - DOMINANDO AL MONSTRUO
Modelo de Datos
Creación del Esquema de Datos
El siguiente video ilustra la creación del esquema VENTAS.
Conexión con la Fuente de Datos
public class AccesoDB {

    private AccesoDB() {
    }

    public static Connection getConnection() throws SQLException{
        Connection cn = null;
        try {
            // --------------------------------------------------
            // Paso 1: Cargar el driver a memoria
            Class.forName("oracle.jdbc.OracleDriver").newInstance();
            // Paso 2: Obtener el objeto Connection
            String url = "jdbc:oracle:thin:@localhost:1521:XE";
            cn = DriverManager.getConnection(url, "ventas", "admin");
            // --------------------------------------------------
        } catch (SQLException e) {
            throw e;
        } catch(ClassNotFoundException e){
            throw new SQLException("No se encontró el driver de la base de datos.");
        } catch(Exception e){
            throw new SQLException("No se puede establecer la conexión con la base de datos.");
        }
        return cn;
    }
}
Implementación de un CRUD
Para la demostración se implementa el CRUD para la tabla PRODUCTO.
Interfaz
public interface ProductoDao {

  /**
   * Transacción controlada desde el cliente
   *
   * @param prod
   */
  void create1(Producto prod);

  /*
   * Transacción controlada en la Base de Datos
   */
  void create2(Producto prod);

  List readAll();

  Producto readForId(int id);

  List readForName(String name);

  void update(Producto prod);

  void delete(int id);
}  
Plantilla para las Consultas
Connection cn = null;
try {
  cn = AccesoDB.getConnection();

  // Consulta
  
} catch (SQLException e) {
    throw new RuntimeException(e.getMessage());
} catch (Exception e) {
  throw new RuntimeException("Error bla bla bla.");
} finally {
  try {
    cn.close();
  } catch (Exception e) {
  }
}
Plantilla para Transacción Desde el Cliente
Connection cn = null;
try {
  cn = AccesoDB.getConnection();
  cn.setAutoCommit(false); // Inicia Tx
  
  // Proceso
  
  cn.commit(); // Confirmar Tx
} catch (SQLException e) {
  try { cn.rollback(); } catch (Exception e1) { }
  throw new RuntimeException(e.getMessage());
} catch (Exception e) {
  try { cn.rollback(); } catch (Exception e1) { }
  throw new RuntimeException("Error bla bla bla.");
} finally {
  try { 
    cn.close(); 
  } catch (Exception e) { }
}
Plantilla para Transacción Desde la Base de Datos
Connection cn = null;
try {
  cn = AccesoDB.getConnection();
  cn.setAutoCommit( true ); 
  
  // Ejecución de procedimiento almacenado
  
} catch (SQLException e) {
  throw new RuntimeException(e.getMessage());
} catch (Exception e) {
  throw new RuntimeException("Error bla bla bla.");
} finally {
  try { 
    cn.close(); 
  } catch (Exception e) { }
}
Implementación
public class OracleProductoDao implements ProductoDao {

  /**
   * Control de transacción desde el cliente
   * @param prod 
   */
    @Override
    public void create1(Producto prod) {
        Connection cn = null;
        try {
            // Variables
      Statement stm;
      PreparedStatement pstm;
            String query;
            int id;
            ResultSet rs;
            // Conexión
            cn = AccesoDB.getConnection();
            // Iniciar la Tx
            cn.setAutoCommit(false);
            // Obtener el Id del producto
            query = "select sq_producto.NextVal id from dual";
            stm = cn.createStatement();
            rs = stm.executeQuery(query);
            rs.next();
            id = rs.getInt("id");
            // Insertar el producto
            query = "insert into producto"
                    + "(idprod,idcat,nombre,precio,stock) "
                    + "values(?,?,?,?,?) ";
            pstm = cn.prepareStatement(query);
            pstm.setInt(1, id);
            pstm.setInt(2, prod.getIdcat());
            pstm.setString(3, prod.getNombre());
            pstm.setDouble(4, prod.getPrecio());
            pstm.setInt(5, prod.getStock());
            pstm.executeUpdate();
            // Retornar el id
            prod.setIdprod(id);
            // Confirmar Tx
            cn.commit();
            // Cerrar objetos
            rs.close();
            stm.close();
            pstm.close();
        } catch (SQLException e) {
            try {
                cn.rollback();
            } catch (Exception e1) {
            }
            throw new RuntimeException(e.getMessage());
        } catch (Exception e) {
            try {
                cn.rollback();
            } catch (Exception e1) {
            }
            throw new RuntimeException("Error en el proceso crear producto.");
        } finally {
            try {
                cn.close();
            } catch (Exception e) {
            }
        }
    }

  /**
   * Control de transacción en el procedimiento almacenado
   * @param prod 
   */
    @Override
    public void create2(Producto prod) {
        Connection cn = null;
        try {
            cn = AccesoDB.getConnection();
            cn.setAutoCommit(true);
            String query = "{call usp_crea_producto(?,?,?,?,?)}";
            CallableStatement cstm = cn.prepareCall(query);
            cstm.registerOutParameter(1, Types.INTEGER);
            cstm.setInt(2, prod.getIdcat());
            cstm.setString(3, prod.getNombre());
            cstm.setDouble(4, prod.getPrecio());
            cstm.setInt(5, prod.getStock());
            cstm.executeUpdate();
            prod.setIdprod(cstm.getInt(1));
            cstm.close();
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage());
        } catch (Exception e) {
            throw new RuntimeException("No se puede crear el producto.");
        } finally {
            try {
                cn.close();
            } catch (Exception e) {
            }
        }
    }

    @Override
    public List readAll() {
        List lista = new ArrayList();
        Connection cn = null;
        try {
            cn = AccesoDB.getConnection();
            String query = "select idprod, idcat, nombre, precio, stock "
                    + "from producto ";
            Statement stm = cn.createStatement();
            ResultSet rs = stm.executeQuery(query);
            while (rs.next()) {
                Producto o = rsToBean(rs);
                lista.add(o);
            }
            rs.close();
            stm.close();
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage());
        } catch(Exception e){
            throw new RuntimeException("No se puede consultar la base de datos.");
        }finally {
            try {
                cn.close();
            } catch (Exception e) {
            }
        }
        return lista;
    }

    @Override
    public Producto readForId(int id) {
        Producto o = null;
        Connection cn = null;
        try {
            cn = AccesoDB.getConnection();
            String query = "select idprod, idcat, nombre, precio, stock "
                    + "from producto "
                    + "where idprod = ?";
            PreparedStatement pstm = cn.prepareStatement(query);
            pstm.setInt(1, id);
            ResultSet rs = pstm.executeQuery();
            if (rs.next()) {
                o = rsToBean(rs);
            }
            rs.close();
            pstm.close();
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage());
        } catch (Exception e) {
            throw new RuntimeException("Error en la lectura del producto.");
        } finally {
            try {
                cn.close();
            } catch (Exception e) {
            }
        }
        return o;
    }

    @Override
    public List readForName(String name) {
        List lista = new ArrayList();
        Connection cn = null;
        try {
            cn = AccesoDB.getConnection();
            String query = "select idprod, idcat, nombre, precio, stock "
                    + "from producto "
                    + "where upper(nombre) like ?";
            PreparedStatement pstm = cn.prepareStatement(query);
            name = "%" + name.toUpperCase() + "%";
            pstm.setString(1, name);
            ResultSet rs = pstm.executeQuery();
            while (rs.next()) {
                Producto o = rsToBean(rs);
                lista.add(o);
            }
            rs.close();
            pstm.close();
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage());
        } catch(Exception e){
            throw new RuntimeException("No se puede consultar la base de datos.");
        } finally {
            try {
                cn.close();
            } catch (Exception e) {
            }
        }
        return lista;
    }

    @Override
    public void update(Producto prod) {
    Connection cn = null;
        try {
            // Variables
            PreparedStatement pstm;
            String query;
            int filas;
            // Conexión
            cn = AccesoDB.getConnection();
            // Iniciar la Tx
            cn.setAutoCommit(false);
            // Insertar el producto
            query = "update producto set idcat=?, nombre=?, precio=?, "
              + "stock=? where idprod = ? ";
            pstm = cn.prepareStatement(query);
            pstm.setInt(1, prod.getIdcat());
            pstm.setString(2, prod.getNombre());
            pstm.setDouble(3, prod.getPrecio());
            pstm.setInt(4, prod.getStock());
            pstm.setInt(5, prod.getIdprod());
            filas = pstm.executeUpdate();
            if(filas == 0){
              throw new SQLException("Producto no existe.");
            }
            // Confirmar Tx
            cn.commit();
            // Cerrar objetos
            pstm.close();
        } catch (SQLException e) {
            try {
                cn.rollback();
            } catch (Exception e1) {
            }
            throw new RuntimeException(e.getMessage());
        } catch (Exception e) {
            try {
                cn.rollback();
            } catch (Exception e1) {
            }
            throw new RuntimeException("Error en el proceso crear producto.");
        } finally {
            try {
                cn.close();
            } catch (Exception e) {
            }
        }
    }

    @Override
    public void delete(int id) {
      Connection cn = null;
      String query;
      PreparedStatement pstm;
      ResultSet rs;
      int cont;
      try {
        cn = AccesoDB.getConnection();
        cn.setAutoCommit(false);
        // Verificar si el producto rgistra ventas
        query = "select count(*) cont from detalle where idprod = ?";
        pstm = cn.prepareStatement(query);
        pstm.setInt(1, id);
        rs = pstm.executeQuery();
        rs.next();
        cont = rs.getInt("cont");
        rs.close();
        pstm.close();
        if (cont > 0) {
          throw new SQLException("El producto registra ventas, no se puede eliminar.");
        }
        // Eliminar el producto
        query = "delete from producto where idprod=?";
        pstm = cn.prepareStatement(query);
        pstm.setInt(1, id);
        int filas = pstm.executeUpdate();
        if (filas == 0) {
          throw new SQLException("Código de producto no existe, "
              + "posiblemente fue eliminado por otro usuario.");
        }
        cn.commit();
        pstm.close();
      } catch (SQLException e) {
        try {
          cn.rollback();
        } catch (Exception e1) {
        }
        throw new RuntimeException(e.getMessage());
      } catch (Exception e) {
        try {
          cn.rollback();
        } catch (Exception e1) {
        }
        throw new RuntimeException("Error al tratar de eliminar el producto.");
      } finally {
        try {
          cn.close();
        } catch (Exception e) {
        }
      }
    }

    private Producto rsToBean(ResultSet rs) throws SQLException {
        Producto o = new Producto();
        o.setIdprod(rs.getInt("idprod"));
        o.setIdcat(rs.getInt("idcat"));
        o.setNombre(rs.getString("nombre"));
        o.setPrecio(rs.getDouble("precio"));
        o.setStock(rs.getInt("stock"));
        return o;
    }
  
}
Video
El siguiente video muestra el funcionamiento del CRUD de la tabla PRODUCTO.

Programación de Procesos de Negocio
Aclarando Conceptos
  • Esta compuesto por varias operaciones que deben trabajar como una sola unidad indivisible.
  • Cada proceso corresponde a un servicio de la capa de negocio.
  • La lógica de persistencia se debe manejar como una transacción y corresponde a un servicio de la capa DAO.
  • Por ejemplo, grabar una venta, es un proceso que involucra varias operaciones que se deben ejecutar como una unidad indivisible.
Interfaz
public interface VentasDao {
  
  void grabarVenta( VentaDto ventaDto);
}
Implementación
public class OracleVentasDao implements VentasDao{

  @Override
  public void grabarVenta(VentaDto ventaDto) {
    Connection cn = null;
    try {
      cn = AccesoDB.getConnection();
      // Inicindo la Tx
      cn.setAutoCommit(false);
      // Obtener el idventa
      String query = "select sq_venta.nextval id from dual";
      Statement stm = cn.createStatement();
      ResultSet rset = stm.executeQuery(query);
      rset.next();
      int idventa = rset.getInt("id");
      // Grabar venta
      query = "insert into venta(IDVENTA,CLIENTE,IDEMP,"
              + "FECHA,IMPORTE) values(?,?,?,sysdate,?)";
      PreparedStatement pstm = cn.prepareStatement(query);
      pstm.setInt(1, idventa);
      pstm.setString(2, ventaDto.getCliente());
      pstm.setInt(3, ventaDto.getIdEmpl());
      pstm.setDouble(4, ventaDto.getImporte());
      pstm.executeUpdate();
      // Grabar los detalles
      query = "insert into detalle(IDVENTA,IDPROD,CANT,"
              + "PRECIO,SUBTOTAL) values(?,?,?,?,?)";
      pstm = cn.prepareStatement(query);
      PreparedStatement pstmLeerStock = cn.prepareStatement("select stock from producto where idprod = ? for update");
      PreparedStatement pstmActStock = cn.prepareStatement("update producto set stock = ? where idprod = ?");
      int stock;
      for ( VentaItem item: ventaDto.getDetalle()) {
        // Verificar stock
        pstmLeerStock.setInt(1, item.getIdprod());
        ResultSet rs = pstmLeerStock.executeQuery();
        rs.next();
        stock = rs.getInt("stock");
        rs.close();
        if(stock < item.getCant()){
          throw new SQLException("No existe stock suficiente de " + item.getNombre() + ".");
        }
        // Actualizar stock
        pstmActStock.setInt(1,  stock - item.getCant());
        pstmActStock.setInt(2, item.getIdprod());
        pstmActStock.executeUpdate();
        // Grabar detalle
        pstm.setInt(1, idventa);
        pstm.setInt(2, item.getIdprod());
        pstm.setInt(3, item.getCant());
        pstm.setDouble(4, item.getPrecio());
        pstm.setDouble(5, item.getSubtotal());
        pstm.executeUpdate();
      }
      // Grabar pagos
      /*  Falta implementar */
      
      // confirmar Tx
      cn.commit();
      ventaDto.setIdventa(idventa);
    } catch (SQLException e) {
      try {
        cn.rollback();
      } catch (Exception e1) {
      }
      throw new RuntimeException(e.getMessage());
    } catch (Exception e) {
      try {
        cn.rollback();
      } catch (Exception e1) {
      }
      throw new RuntimeException("Error en el proceso Grabar Venta.");
    } finally {
      try {
        cn.close();
      } catch (Exception e) {
      }
    }
  }
  
}
Video
El siguiente video muestra el funcionamiento del proceso de venta.
DESCARGAR PROYECTO
CODIGO FUENTE
En esta sección te presento un video de una aplicación CLIENTE-SERVIDOR.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.



LIBRO DE PHP

En esta oportunidad les presento mi libro PHP PROFESIONAL, donde se desarrollan temas desde básicos hasta avanzados, como PHP Data Object, patrones MVC, DAO, etc.
Les comento que ya esta a la venta mi nuevo libro de PHP titulado: PHP Profesional.


Pueden bajar un capitulo de ejemplo desde el siguiente enlace: Bajar Archivo

CODIGO FUENTE

En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.

Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.




Grabar Imagen en Base de Datos Utilizando JDBC

GRABAR IMAGEN EN BASE DE DATOS UTILIZANDO JDBC
Software a Utilizar
  • NetBeans 6.9
  • MySQL 5.1
Tipo de Aplicación

Para este ejercicio se creará una aplicación de tipo Cliente/Servidor cuya interfaz se ilustra a continuación:

Tipo de Dato

Para grabar una imagen en una base de datos MySQL debemos utilizar el tipo de dato BLOB, para este caso utilizaremos la tabla PRODUCTO cuya estructura se muestra a continuación:

mysql> describe producto;
+-----------------+---------------+------+-----+---------+----------------+
| Field           | Type          | Null | Key | Default | Extra          |
+-----------------+---------------+------+-----+---------+----------------+
| PRO_ID          | int(11)       | NO   | PRI | NULL    | auto_increment |
| AUT_ID          | int(11)       | NO   | MUL | NULL    |                |
| CAT_ID          | int(11)       | NO   | MUL | NULL    |                |
| EDI_ID          | int(11)       | NO   | MUL | NULL    |                |
| PRO_NOMBRE      | varchar(100)  | NO   |     | NULL    |                |
| PRO_DESCRIPCION | text          | YES  |     | NULL    |                |
| PRO_STOCK       | int(11)       | NO   |     | NULL    |                |
| PRO_PRECIO      | decimal(10,2) | NO   |     | NULL    |                |
| PRO_FOTO        | blob          | YES  |     | NULL    |                |
+-----------------+---------------+------+-----+---------+----------------+
9 rows in set (0.04 sec)
Clase Entity

La clase entity para la tabla PRODUCTO quedaría implementada de la siguiente manera:

package dao.entity;

     private int id;
     private int autor;
     private int categoria;
     private int editorial;
     private String nombre;
     private String descripcion;
     private int stock;
     private double precio;
     private byte[] foto;

     // Implementar los métodos getters y setters
}

Para la columna de tipo blob se crea un campo de tipo ARRAY de BYTES.

Capa de Lógica de Persistencia

El método que corresponde a la capa de persistencia que crea un nuevo producto en la base de datos se implementa de la siguiente manera:

package dao.componentes;

import dao.database.AccesoDB;
import dao.entity.Producto;
import dao.interfaces.IProductoDAO;
import excepcion.TiendaException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;


public class ProductoDAO implements IProductoDAO {

  public void crear(Producto prod) throws TiendaException {
    Connection cn = null;
    PreparedStatement pstm = null;
    try {
        cn = AccesoDB.getConnection();
        cn.setAutoCommit(false);
        String query = "insert into producto(AUT_ID,CAT_ID,EDI_ID,PRO_NOMBRE," +
                    "PRO_DESCRIPCION,PRO_STOCK,PRO_PRECIO,PRO_FOTO) " +
                    "values(?,?,?,?,?,?,?,?)";
        pstm = cn.prepareStatement(query);
        pstm.setInt(1, prod.getAutor());
        pstm.setInt(2, prod.getCategoria());
        pstm.setInt(3, prod.getEditorial());
        pstm.setString(4, prod.getNombre());
        pstm.setString(5, prod.getDescripcion());
        pstm.setInt(6, prod.getStock());
        pstm.setDouble(7, prod.getPrecio());
        pstm.setBytes(8, prod.getFoto());
        pstm.executeUpdate();
        cn.commit();
    } catch (Exception e) {
        try {
             cn.rollback();
        } catch (Exception e1) {
        }
        throw new TiendaException(e.getMessage());
    } finally {
        try {
             pstm.close();
        } catch (Exception e) {
        }
    }
  }

  . . .
  . . .
}
Acceso a la Capa DAO

Para acceder a la capa DAO se utiliza una capa model implementada de la siguiente manera:

package model;

import dao.componentes.ProductoDAO;
import dao.entity.Producto;
import excepcion.TiendaException;
import java.util.List;

public class CatalogoModel {

     public void crearProducto( Producto prod) throws TiendaException{
          new ProductoDAO().crear(prod);
     }

     . . .
     . . .
}
Implementación de la Capa View

Primero se debe seleccionar el archivo para lo cual se ha implementado el botón Buscar [...], el script es el siguiente:

private void btnBuscarFotoActionPerformed(java.awt.event.ActionEvent evt) {                                             

  JFileChooser openFile = new JFileChooser();
  int returnValue = openFile.showOpenDialog(this);
  if (returnValue == JFileChooser.CANCEL_OPTION) {
      return;
  }
  File archivo = openFile.getSelectedFile();
  this.txtFoto.setText(archivo.getAbsolutePath());
  ImageIcon tmp = new ImageIcon(archivo.getAbsolutePath());
  ImageIcon imagen = new ImageIcon(tmp.getImage().getScaledInstance(
  this.lblFoto.getWidth(),
  this.lblFoto.getHeight(),
  Image.SCALE_DEFAULT));
  this.lblFoto.setIcon(imagen);

}

Y para grabar el registro en la base de datos se ha implementado el botón Grabar, el script es el siguiente:

private void btnGrabarActionPerformed(java.awt.event.ActionEvent evt) {                                         

  try {

      Producto prod = new Producto();
      prod.setAutor(listaAutores.get(cboAutor.getSelectedIndex()).getId());
      prod.setCategoria(listaCategorias.get(cboCategoria.getSelectedIndex()).getId());
      prod.setEditorial(listaEditoriales.get(cboEditorial.getSelectedIndex()).getId());
      prod.setNombre(txtNombre.getText());
      prod.setDescripcion(txtDescripcion.getText());
      prod.setStock(Integer.parseInt(txtStock.getText()));
      prod.setPrecio(Double.parseDouble(txtPrecio.getText()));

      // Obtener la imagen
      File archivo = new File(this.txtFoto.getText());
      byte[] imgFoto = new byte[(int) archivo.length()];
      InputStream input = new FileInputStream(archivo);
      input.read(imgFoto);
      prod.setFoto(imgFoto);

      model.crearProducto(prod);
      utilitarios.Util.showMessage("Producto creado en la base de datos satisfactoriamente.");
      limpiarFormulario();

  } catch (Exception e) {
      utilitarios.Util.showError("ERROR: " + e.getMessage());
  }

} 
Código Fuente de la Aplicación

Para obtener la aplicación ejemplo utilice el siguiente enlace:

Descargar Código Fuente de la Aplicación
CODIGO FUENTE
En esta sección te presento un video de una aplicación CLIENTE-SERVIDOR.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.