Escolar Documentos
Profissional Documentos
Cultura Documentos
8
En esta gua se crear una aplicacin con acceso a bases de datos que permita gestionar los artculos y sus respectivos movimientos, ser algo sencillo, pero sustancial, se aplicarn los patrones de diseos: Data Transfer Object (DTO), Data Access Object (DAO), Session Facade y Bussines delegate, todo esto para cumplir con el patron arquitectonico Modell - View - Controller.
asuncionez@hotmail.com
Pgina 1
Conceptos Bsicos.
Patrn de Diseo Un patrn de diseo es una abstraccin de una solucin en un nivel alto. Los patrones solucionan problemas que existen en muchos niveles de abstraccin. Hay patrones que abarcan las distintas etapas del desarrollo; desde el anlisis hasta el diseo y desde la arquitectura hasta la implementacin. Entonces un patrn de diseo es un conjunto de reglas que describen como afrontar tareas y solucionar problemas que surgen durante el desarrollo de software. Los patrones de diseo empezaron a reconocerse a partir de las descripciones de varios autores a principios de 1990, el cual culmina en el ao 1995 con la publicacin del libro "Design Patterns -- Elements of Reusable Software" de Gamma, Helm, Johnson y Vlissides; conocidos como GOF (Gang of Four, la pandilla de los 4).
modelo de datos.
asuncionez@hotmail.com
Pgina 2
El script sql de creacin. DROP SCHEMA IF EXISTS EzjaMVC; CREATE SCHEMA IF NOT EXISTS EzjaMVC; USE EzjaMVC; CREATE TABLE IF NOT EXISTS Articulo ( claveArticulo CHAR(10) NOT NULL , descripcion VARCHAR(50) NOT NULL , precio DECIMAL(12,2) NOT NULL , existencias INT NOT NULL , PRIMARY KEY (claveArticulo)); CREATE TABLE IF NOT EXISTS Movimientos( folio CHAR(18) NOT NULL , fecha DATE NOT NULL , tipoMov CHAR(1) NOT NULL , cantidad INT NOT NULL , claveArticulo CHAR(10) NOT NULL , PRIMARY KEY (folio) , INDEX fk_Movimientos_Articulo (claveArticulo ASC) , CONSTRAINT fk_Movimientos_Articulo FOREIGN KEY (claveArticulo) REFERENCES Articulo (claveArticulo) ON DELETE CASCADE ON UPDATE CASCADE);
asuncionez@hotmail.com
Pgina 3
Creacin del la Bd
asuncionez@hotmail.com
Pgina 4
asuncionez@hotmail.com
Pgina 5
6. Terminar o Finish
asuncionez@hotmail.com
Pgina 6
Lo primero que haremos ser crear la estructura de paquetes a utilizar en el proyecto, para crear un paquete en NetBeans, se crearan los siguientes paquetes: 1. com.ezjamvc.modelo.dto 2. com.ezjamvc.modelo.dao 3. com.ezjamvc.modelo.facade 4. com.ezjamvc.modelo.delegate 5. com.ezjamvc.vista.formularios
asuncionez@hotmail.com
Pgina 7
asuncionez@hotmail.com
Pgina 8
asuncionez@hotmail.com
Pgina 9
asuncionez@hotmail.com
Pgina 10
Ahora que tenemos la estructura de la clase ArticuloDTO, la codificacin se realizar de acuerdo al siguiente Diagrama de Clases.
asuncionez@hotmail.com
Pgina 11
Por lo tanto la codificacin de la clase quedaria de la siguiente forma. package com.ezjamvc.modelo.dto; import java.io.Serializable; /*** @author asuncion */ public class ArticuloDTO implements Serializable { private private private private String claveArticulo; String descripcion; double precio; int existencias;
public ArticuloDTO() { } public String getClaveArticulo() { return claveArticulo; } public void setClaveArticulo(String claveArticulo) { this.claveArticulo = claveArticulo; } public String getDescripcion() { return descripcion; } public void setDescripcion(String descripcion) { this.descripcion = descripcion; } public int getExistencias() { return existencias; } public void setExistencias(int existencias) { this.existencias = existencias; }
asuncionez@hotmail.com
Pgina 12
public double getPrecio() { return precio; } public void setPrecio(double precio) { this.precio = precio; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Clave Articulo ").append(getClaveArticulo()).append("\n"); sb.append("Descripcion Articulo ").append(getDescripcion()).append("\n"); sb.append("Precio Articulo ").append(getPrecio()).append("\n"); sb.append("Existencias Articulo ").append(getExistencias()).append("\n"); return sb.toString(); } }
asuncionez@hotmail.com
Pgina 13
De acuerdo con el diagrama, es necesario crear la clase ArticuloDAO, que de acuerdo con el patrn Data Access Object, es el encargado de encapsular la lgica de acceso a bases de datos. Aclarando solo mostrare una forma de hacerlo, de preferencia seguir las indicaciones, del enlace de arriba y considerar las notas que pondre al final.
asuncionez@hotmail.com
Pgina 14
Por lo tanto la codificacin de la clase quedara de la siguiente forma. package com.ezjamvc.modelo.dao; import com.ezjamvc.modelo.dto.ArticuloDTO; import java.sql.Connection; import import import import import java.sql.PreparedStatement; java.sql.ResultSet; java.sql.SQLException; java.util.ArrayList; java.util.List;
/*** @author asuncion */ public class ArticuloDAO { private static final String SQL_INSERT = "INSERT INTO Articulo (" + "claveArticulo, descripcion, precio, existencias" + ") VALUES (?, ?, ?, ?)"; private static final String SQL_SELECT = "SELECT claveArticulo, descripcion, precio, existencias " + " FROM Articulo where claveArticulo= ?"; private static final String SQL_SELECT_All = "SELECT claveArticulo, descripcion, precio, existencias " + "FROM Articulo"; private static final String SQL_UPDATE = "UPDATE Articulo SET " + "descripcion = ?, precio = ?, existencias = ?" + " WHERE " + "claveArticulo = ? "; /* SQL to delete data */ private static final String SQL_DELETE = "DELETE FROM Articulo WHERE " + "claveArticulo = ?";
asuncionez@hotmail.com
Pgina 15
public void create(ArticuloDTO dto, Connection conn) throws SQLException { PreparedStatement ps = null; try { ps = conn.prepareStatement(SQL_INSERT); ps.setString(1, dto.getClaveArticulo()); ps.setString(2, dto.getDescripcion()); ps.setDouble(3, dto.getPrecio()); ps.setInt(4, dto.getExistencias()); ps.executeUpdate(); } finally { cerrar(ps); cerrar(conn); } } public ArticuloDTO load(ArticuloDTO dto, Connection conn) throws SQLException { PreparedStatement ps = null; ResultSet rs = null; try { ps = conn.prepareStatement(SQL_SELECT); ps.setString(1, dto.getClaveArticulo()); rs = ps.executeQuery(); List results = getResults(rs); if (results.size() > 0) { return (ArticuloDTO) results.get(0); } else { return null; } } finally { cerrar(rs); cerrar(ps); cerrar(conn); } }
asuncionez@hotmail.com
Pgina 16
public List loadAll(Connection conn) throws SQLException { PreparedStatement ps = null; ResultSet rs = null; try { ps = conn.prepareStatement(SQL_SELECT_All); rs = ps.executeQuery(); List results = getResults(rs); if (results.size() > 0) { return results; } else { return null; } } finally { cerrar(rs); cerrar(ps); cerrar(conn); } } public void update(ArticuloDTO dto, Connection conn) throws SQLException { PreparedStatement ps = null; try { ps = conn.prepareStatement(SQL_UPDATE); ps.setString(1, dto.getDescripcion()); ps.setDouble(2, dto.getPrecio()); ps.setInt(3, dto.getExistencias()); ps.setString(4, dto.getClaveArticulo()); ps.executeUpdate(); } finally { cerrar(ps); cerrar(conn); } }
asuncionez@hotmail.com
Pgina 17
public void delete(ArticuloDTO dto, Connection conn) throws SQLException { PreparedStatement ps = null; try { ps = conn.prepareStatement(SQL_DELETE); ps.setString(1, dto.getClaveArticulo()); ps.executeUpdate(); } finally { cerrar(ps); cerrar(conn); } } private List getResults(ResultSet rs) throws SQLException { List results = new ArrayList(); while (rs.next()) { ArticuloDTO dto = new ArticuloDTO(); dto.setClaveArticulo(rs.getString("claveArticulo")); dto.setDescripcion(rs.getString("descripcion")); dto.setPrecio(rs.getDouble("precio")); dto.setExistencias(rs.getInt("existencias")); results.add(dto); } return results; } private void cerrar(PreparedStatement ps) throws SQLException { if (ps != null) { try { ps.close(); } catch (SQLException e) { } } }
asuncionez@hotmail.com
Pgina 18
private void cerrar(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { } } } private void cerrar(Connection cnn) { if (cnn != null) { try { cnn.close(); } catch (SQLException e) { } } } } Despus de haber creado la clase ArticuloDAO, (solo para no aburrirse y ver que estamos haciendo y que realmente este funcionando, se crear una clase java simple que utilice a ArticuloDAO y verificar el funcionamiento de las operaciones CRUD en nuestra base de datos). Lo primero es agregar a nuestro proyecto la librera para poder conectar con MySql, por lo tanto en la estructura del proyecto buscamos: Bibliotecas(Libraries) ==> le damos clic con el botn derecho del mouse y elegimos la opcin Agregar Biblioteca, aparece el siguiente cuadro
asuncionez@hotmail.com
Pgina 19
en el cual elegir la opcin Driver MYSQL JDBC y con esto el proyecto ya podr mantener comunicacin con el servidor de bases de datos MySql. La clase de prueba, se crear en la raz del proyecto as que basta con seleccionar el nodo paquetes de fuentes (sources packages) del proyecto, botn derecho ==>nuevo ==>clase java.
asuncionez@hotmail.com
Pgina 20
El codigo es el siguiente: import com.ezjamvc.modelo.dao.ArticuloDAO; import com.ezjamvc.modelo.dto.ArticuloDTO; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; /** @author asuncion */ public class PruebaDAO { public PruebaDAO() { } public static void main(String[] args) { /* * Solo para probar el funcionamiento */ Connection cnn = null; 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(); } //Crear una Instacia del DTO ArticuloDTO dto = new ArticuloDTO(); //Crear una instacia del DAO ArticuloDAO dao = new ArticuloDAO(); try { //Agregar un registro nuevo //dto.setClaveArticulo("art100"); //dto.setDescripcion("libreta"); //dto.setExistencias(100); //dto.setPrecio(5000); //dao.create(dto, cnn);
asuncionez@hotmail.com
Pgina 21
//Actualizar un registro existente //dto.setClaveArticulo("art100"); //dto.setDescripcion("lap hp "); //dto.setExistencias(100); //dto.setPrecio(5000); //dao.update(dto, cnn); //Mostrar un solo registro //dto.setClaveArticulo("art100"); //dto = dao.load(dto, cnn); //System.out.println(dto); //Eliminar un registro //dto.setClaveArticulo("art100"); //dao.delete(dto, cnn); //Listar los registros System.out.println(dao.loadAll(cnn)); } catch (SQLException ex) { Logger.getLogger(PruebaDAO.class.getName()).log(Level.SEVERE, null, ex); } } } El resultado aparece en la parte inferior del IDE, de la siguiente forma
asuncionez@hotmail.com
Pgina 22
Segn sea el caso de las opciones que decomenten para ejecutar, sern los resultados que se obtendrn en la bd. Nota, decomentar solo una accin a la vez, ya que en cada una de ellas se abre y se cierra la conexin al inicio y al final respectivamente.
asuncionez@hotmail.com
Pgina 23
Esta imagen muestra como en la base de datos se actualizan los datos de art100, despus se elimina, segn la secuencia, de cmo se comentaron las acciones, crear, actualizar, buscar eliminar y mostrar todos.
asuncionez@hotmail.com
Pgina 24
asuncionez@hotmail.com
Pgina 25
Por lo tanto la codificacin de la clase quedara de la siguiente forma. package com.ezjamvc.modelo.facade; import import import import import com.ezjamvc.modelo.dao.ArticuloDAO; com.ezjamvc.modelo.dto.ArticuloDTO; java.sql.Connection; java.sql.SQLException; 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); } }
asuncionez@hotmail.com
Pgina 26
Lo interesante de esta clase es que el constructor recibe como parmetro la conexin a la base de datos.
asuncionez@hotmail.com
Pgina 27
Por lo tanto la codificacin de la clase quedara de la siguiente forma. package com.ezjamvc.modelo.delegate; import com.ezjamvc.modelo.dto.ArticuloDTO; import com.ezjamvc.modelo.facade.ArticuloFacade; import import import import java.sql.Connection; java.sql.DriverManager; java.sql.SQLException; java.util.List;
/** * * @author asuncion */ public class EzjaMVCDelegate { private Connection cnn; private ArticuloFacade artFacade;
asuncionez@hotmail.com
Pgina 28
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); } }
asuncionez@hotmail.com
Pgina 29
Al revisar el cdigo, nos podemos dar cuenta que al momento de definir el constructor, se obtiene una conexin a la base de datos, la cual se pasa como parmetro a la instancia de ArticuloFacade que se crea. Nota: No es recomendable indicar los datos de la conexin dentro del cdigo java (cdigo Duro), lo ms elegante sera ponerlo en un archivo de configuracin, del color que ms les guste (archivo properties, xml, etc).
asuncionez@hotmail.com
Pgina 30
Ahora modificaremos ligeramente la clase de prueba para verificar el funcionamiento de la aplicacin, utilizando ya la clase que implementa el patrn delegate. 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);
asuncionez@hotmail.com
Pgina 31
//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); } } }
asuncionez@hotmail.com
Pgina 32
Basta con asignarle nombre, y verificar que los datos mostrados sean los correctos
Clic en Terminar. Despus de haber creado la clase ArticuloForm aparece en pantalla el diseador de formularios Matisse, el cual permite disear una interfaz grafica de usuario con solo hacer clic arrastrar y soltar componentes (Drag & Drog). Siendo sus partes las siguientes 1. rea de trabajo, aqu es en donde se insertaran los controles que darn forma al formulario. 2. Cuadro de controles, aqu se encuentran todos los componentes que se pueden agregar al formulario (Cuadros de texto, Etiquetas, Tablas, etc.), con solo arrastrar y soltar. 3. Cuadro de propiedades, desde aqu es posible modificar las propiedades (caractersticas) del componente (objeto) seleccionado, como el nombre, tipo de fuente, etc. 4. Opcin para mostrar el cdigo fuente del formulario, si previamente se est en la vista diseo de formulario. 5. Opcin para mostrar el diseo formulario, si previamente se est en la vista cdigo fuente.
asuncionez@hotmail.com
Pgina 33
2
4 5 6
asuncionez@hotmail.com
Pgina 34
Una vez que se ha identificado cada una de las partes del diseador de interfaces graficas de usuario, se procede a crear la interfaz de Artculo.
asuncionez@hotmail.com
Pgina 35
asuncionez@hotmail.com
Pgina 36
Ahora agregar los cuadros de texto, en el nodo swing controls del cuadro de herramientas clic en el control campo de texto (Text Field), darle clic y dibujarlo en el formulario. Quedando de la siguiente manera.
Por ltimo agregar los botones, en el nodo swing controls del cuadro de herramientas clic en el control botn (JButton) , darle clic y dibujarlo en el formulario. Quedando de la siguiente manera.
asuncionez@hotmail.com
Pgina 37
Para cambiarle el texto a cualquier control, basta con seleccionarlo, darle clic con el botn derecho y elegir la opcin Editar texto.
Modificar el texto de las etiquetas, los cuadros de texto y los botones, con los siguientes valores.
Valor Original jLabel1 jLabel2 jLabel3 jLabel4 jTextField1 jTextField2 jTextField3 jTextField4 jButton1 jButton2 jButton3 Nuevo Valor Clave Articulo Descripcin Precio Existencias En Blanco En Blanco En Blanco En Blanco Nuevo Buscar Actualizar
asuncionez@hotmail.com
Pgina 38
Ahora, cada control aun conservan los nombres por defecto: jButton1, jLabel1, jTextField1, etc. Lo ideal es cambiarles el nombre a cada control. Para cambiarle el nombre a cualquier control, basta con seleccionarlo, darle clic con el botn derecho y elegir la opcin Editar texto.
asuncionez@hotmail.com
Pgina 39
Modificar el nombre de las etiquetas, los cuadros de texto y los botones, con los siguientes valores.
Valor Original jLabel1 jLabel2 jLabel3 jLabel4 jTextField1 jTextField2 jTextField3 jTextField4 jButton1 jButton2 jButton3 Nuevo Valor jlbClaveArticulo jlbDescripcion jlbPrecio jlbExistencia jtfClaveArticulo jtfDescripcion jtfPrecio jtfExistencias jbtNuevo jbtBuscar jbtActualizar
Una vez realizado lo anterior ya es posible programar la funcionalidad de cada uno de los botones, como primer paso es necesario darle funcionalidad al formulario desde cdigo, es decir declarar como atributos privados una instancia del EzjaMVCDelegate e inicializarlo en null, ArticuloDTO e inicializarlo en el constructor, adems, se hace la declaracin de un Look & Feel, solo por darle presentacin, es un tema para la aplicacin .
asuncionez@hotmail.com
Pgina 40
Despus de ello a programar que funcionalidad tendrn cada uno de los botones como respuesta a un evento por parte del usuario. Hay dos formas de programar la funcionalidad, por medio de un Action Performed o de un Mouse clicked.
asuncionez@hotmail.com
Pgina 41
Explicacin por Lneas de cdigo 165. Se crea la instancia fsica de la clase EzjaMVCDelegate. 166. A la instancia de ArticuloDTO llamada dto se le asigna el valor contenido en el cuadro de texto correspondiente a la clave del Artculo. 167. A la instancia de ArticuloDTO llamada dto se le asigna el valor contenido en el cuadro de texto correspondiente a la existencia del Artculo. Nota: Si los atributos en el dto son de tipo texto, solo basta con poner el nombre del cuadro de texto y llamar al mtodo getText(), debido a que todo cuadro de texto regresa una cadena de texto. 169. A la instancia de ArticuloDTO llamada dto se le asigna el valor contenido en el cuadro de texto correspondiente a la Descripcin del Artculo. Nota: Si los atributos en el dto son de tipo diferente a texto, es necesario realizar un casting, para convertir el valor obtenido del cuadro de texto que es de tipo String a su correspondiente valor numrico, en este caso Integer.parseInt(valor). 170 171. Entre estas lneas debiera de ir el cdigo correspondiente al tratamiento del error. 176 181. El bloque try catch, hace una llamada al mtodo
asuncionez@hotmail.com
Pgina 42
crearArticulo, de la clase delegate (lnea 177), en caso de algn error se lanza la excepcin correspondiente la cual es tratada en la lnea 179 180, y solo aparece una traza en modo consola.
Explicacin por Lneas de cdigo 185. Se crea la instancia fsica de la clase EzjaMVCDelegate. 186. A la instancia de ArticuloDTO llamada dto se le asigna el valor contenido en el cuadro de texto correspondiente a la clave del Artculo, que es el nico campo necesario para realizar la bsqueda. 187 198. Inicia el bloque try catch. 188.- Se ejecuta el mtodo leerArticulo de la clase delegate pasando como parmetro la instancia de la clase ArticuloDTO, llamada dto, la cual conoce el valor de la clave del articulo a buscar, el mtodo leerArticulo, regresa una instancia de ArticuloDTO (un registro de la tabla en la base de datos), el cual se le asigna a la instancia misma del dto, para poder ser procesada. 189.- si la instancia del dto es diferente de null, es decir trae valores, se proceder a llenar los cuadros de texto, con dichos valores, en caso contrario si es null, es decir no trae nada que nos
asuncionez@hotmail.com
Pgina 43
interese, no har nada (193 - 194), pero es aqu en donde sera conveniente mostrar algn mensaje avisando que no s encontraron datos. En las lneas 190 192, se hace la asignacin de los valores que trae el objeto dto, a los cuadros de texto, considerando que si son valores de tipo cadena (String), se asignan de forma directa (190), pero si son de algn valor numrico del tipo que sea es necesario pasarlos a cadena con String.valueOf (191 192) 195 198. En caso de algn error se lanza la excepcin correspondiente la aparece una traza en modo consola.
asuncionez@hotmail.com
Pgina 44
Explicacin por Lneas de cdigo 213. Se crea la instancia fsica de la clase EzjaMVCDelegate. 214. A la instancia de ArticuloDTO llamada dto se le asigna el valor contenido en el cuadro de texto correspondiente a la clave del Artculo y a su descripcin (215). 216 - 219. Inicia el bloque try catch, para agregar la existencia, el cual por ser un nmero entero, es necesario realizar un parsing Integer.parseInt, ya que el valor del cuadro de texto es de tipo String. 220 223.- Inicia el bloque try catch, para agregar el precio, el cual por ser un nmero fraccionario, es necesario realizar un parsing Double.parseDouble, ya que el valor del cuadro de texto es de tipo String. 224 -229. Se ejecuta el mtodo actualiza de la clase delegate pasando como parmetro la instancia de la clase ArticuloDTO, llamada dto. 227.- En caso de algn error se lanza la excepcin correspondiente la aparece una traza en modo consola.
asuncionez@hotmail.com
Pgina 45