
Ampliación del Modelo Vista Controlador en Java y MySQL
15 octubre, 2015 ◆ 4 comentariosEn este artículo ampliaremos el tutorial (enlace al tutorial) que muestra paso a paso cómo construir una aplicación en Java usando el patrón Modelo Vista Controlador (MVC) ya que ha habido varias consultas y peticiones al respecto.
La ampliación consiste en añadir la posibilidad de filtrar en la gestión de clientes. De este modo, se permite buscar un cliente en concreto mediante su id, nombre o apellido.
Este artículo parte del ejemplo del tutorial Modelo Vista Controlador en Java y MySQL, nivel básico. A él vamos a añadirle la opción de búsqueda de modo que el resultado final será el mostrado en la siguiente imagen:
Para ello:
- En la Vista se realizará una modificación para contemplar el JLabel, JTextField y JButton.
- En el Controlador se añadirá la escucha del botón Buscar. Y se sobrecargará el método cargarTabla con un parámetro de entrada.
- En la base de datos se añadirá un nuevo procedimiento almacenado para realizar la búsqueda de un cliente.
Vista
Como se ha comentado en el anterior artículo, en este fichero se lleva a cabo el diseño de la ventana de nuestra aplicación.
Se definen tres nuevas propiedades:
- JLabel para la etiqueta Buscar.
- JTextField donde se introducirá el identificador, nombre o apellido a buscar.
- JButton para realizar la búsqueda.
En el constructor se crean dichas propiedades y se añaden al contenedor siguiendo la misma filosofía empleada de SpringLayout.
Por último, en el método conectaControlador se añade actionListener y actionCommand al botón para que desencadene una acción en el controlador.
El nuevo código quedaría tal y como se muestra a continuación:
package kadumMVC; public class View extends JFrame { private static final long serialVersionUID = 1L; //ETIQUETAS [...] private JLabel lblBuscar; //CUADROS DE TEXTO [...] protected JTextField txtBuscar; //BOTONES [...] protected JButton btnBuscar; [...] /**************** MÉTODOS ***************************/ //CONSTRUCTOR View(){ [...] //etiqueta buscar lblBuscar = new JLabel("Buscar:"); contenedor.add(lblBuscar); sp.putConstraint(SpringLayout.NORTH, lblBuscar, 120, SpringLayout.NORTH, contenedor); sp.putConstraint(SpringLayout.WEST, lblBuscar, 10, SpringLayout.WEST, contenedor); /**************** EOF ETIQUETAS ^^^^^^^^^^^^^^^^^^^^ **/ /**************** BOF CUADROS DE TEXTO vvvvvvvvvvvvvvvvvvvv **/ [...] //cuadro de texto para buscar txtBuscar = new JTextField(); contenedor.add(txtBuscar); //añadir al contenedor sp.putConstraint(SpringLayout.NORTH, txtBuscar, 120, SpringLayout.NORTH, contenedor); sp.putConstraint(SpringLayout.WEST, txtBuscar, 100, SpringLayout.WEST, contenedor); sp.putConstraint(SpringLayout.EAST, txtBuscar, 300, SpringLayout.WEST, contenedor); /**************** EOF CUADROS DE TEXTO ^^^^^^^^^^^^^^^^^^^^ **/ [...] /**************** BOF BOTONES vvvvvvvvvvvvvvvvvvvv **/ [...] //boton buscar btnBuscar = new JButton("Buscar"); contenedor.add(btnBuscar); sp.putConstraint(SpringLayout.SOUTH, btnBuscar, 140, SpringLayout.NORTH, contenedor); sp.putConstraint(SpringLayout.WEST, btnBuscar, 310, SpringLayout.WEST, contenedor); /**************** EOF BOTONES ^^^^^^^^^^^^^^^^^^^^ **/ //Se hace visible la ventana setVisible(true); } public void conectaControlador( Controller c ){ [...] btnBuscar.addActionListener(c); btnBuscar.setActionCommand("BUSCAR"); tabla.addMouseListener(c); tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //sólo se puede pulsar una fila } }
Controlador
En el método actionPerformed, se tiene un switch para cada comando ejectuado (INSERTAR, BORRAR y MODIFICAR). El método concluye con una llamada a cargarTabla().
La idea que se lleva a cabo es añadir una nueva opción al switch para contemplar el comando BUSCAR.
Al final del método, si se pulsa sobre el botón buscar, en lugar de llamar al método cargarTabla(), sin parámetros, se llamará a ese método pero con un parámetro de entrada, de modo que se deberá sobrecargar cargarTabla(String buscar). El parámetro de entrada con el cual se llama será la información que se escriba en el JTextField.
El método sobrecargado se encargará de llamar al procedimiento almacenado filtrarCliente que se describe posteriormente.
El código resultante es:
package kadumMVC; [...] public class Controller implements ActionListener, MouseListener { @Override public void actionPerformed(ActionEvent arg0) { [...] //Se almacena la informacion a buscar String buscar = ""; [...] switch (comando) { case "INSERTAR": [...] break; case "BORRAR": [...] break; case "MODIFICAR": [...] case "BUSCAR": //Obtener el valor buscado buscar = this.view.txtBuscar.getText(); break; default: System.err.println("Comando no definido"); break; } //limpiar el formulario limpia(); //Se añade la condición para cargar la tabla if(comando!="BUSCAR"){ //Carga normal cargarTabla(); }else{ //Cargar la tabla con criterio de búsqueda cargarTabla(buscar); } } //Método para limpiar los campos de la ventana private void limpia(){ this.view.txtNombre.setText(""); this.view.txtApellido.setText(""); this.view.txtNIF.setText(""); //Limpiamos el nuevo campo de texto this.view.txtBuscar.setText(""); } //No se modifica nada protected void cargarTabla(){ [...] } /* SOBRECARGA DEL MÉTODO PARA OBTENER SOLO LOS CLIENTES QUE CUMPLEN CON LA CONDICIÓN DE BÚSQUEDA */ protected void cargarTabla(String buscar){ CallableStatement cs; ResultSet rs; Vector<Object> fila; for(int i=this.view.dtm.getRowCount(); i>0; i--){ this.view.dtm.removeRow(i-1); } //Cargar datos en la tabla CON LOS CLIENTES BUSCADOS try { //Preparar la llamada cs = Bd.getConexion().prepareCall("{CALL filtrarCliente(?)}"); cs.setString(1, buscar); //Ejecutarla y recoger el resultado rs = cs.executeQuery(); //Recorrer el resultado while(rs.next()){ //Añadir registro a registro en el vector fila = new Vector<Object>(); fila.add(rs.getInt("id")); fila.add(rs.getString("nombre")); fila.add(rs.getString("nif")); //Añadir el vector a la tabla de la clase View this.view.dtm.addRow(fila); } } catch (SQLException e) { System.err.println("Error al CARGAR DATOS"); } } [...] }
Procedimiento almacenado
Cuando se pulsa el botón buscar, el controlador llama al procedimiento almacenado filtrarCliente. Este método debe devolver el id, nombre y NIF de los clientes que coincidan con el parámetro de búsqueda.
Recordamos que se deben devolver esos 3 campos porque son los que se muestran en nuestra tabla.
El procedimiento en nuestra base de datos MySQL será:
DELIMITER $$ DROP PROCEDURE IF EXISTS filtrarCliente$$ CREATE PROCEDURE filtrarCliente(buscar VARCHAR(50)) BEGIN SELECT id, nombre, nif FROM cliente WHERE cliente.id= buscar OR cliente.nombre LIKE CONCAT('%',buscar,'%') OR cliente.apellido LIKE CONCAT('%',buscar,'%'); END $$
Donde se observa que recibe un parámetro de entrada que se utiliza en el WHERE de la condición para obtener los clientes cuyo id, nombre o apellido coincidan con dicho parámetro.
MVC Resultado
Tras realizar estas ampliaciones se podrán realizar búsquedas sobre los clientes almacenados. En la siguiente captura de pantalla se realiza la búsqueda del cliente con identificador igual a 2.
Tras pulsar el botón Buscar, se carga en la tabla los clientes que coinciden con la búsqueda.
Al pulsar sobre el cliente que nos interesa, se cargarán sus datos en los diferentes JTextField por lo que se podrá llevar a cabo su modificación o eliminación.
Espero que esta ampliación de la funcionalidad de la aplicación sirva para afianzar los conceptos explicados sobre modelo vista controlador y emplearla como base para mejorar vuestro modelo con más funcionalidades.
holaa men, me gustaria saber en donde van las validaciones y ese tipo de cosas en el mvc, gracias por este buen aportee
Buenas, Diego:
Te refieres a realizar la validación del tipo: que se rellenen los campos para el nombre y apellidos, que el DNI sea correcto o, si existiera un campo para el correo electrónico, que el mail esté en un formato adecuado, ¿verdad?
Cuando se emplea el patrón Modelo Vista Controlador lo idóneo es realizar ese tipo de validaciones en el Controlador. Por lo tanto, en la clase Controller en el método actionPerformed se debería llevar a cabo las validaciones oportunas.
Un saludo.
que tal, como puedo bajar el codigo?? salu2
Hola, lalo:
El código de este ejemplo no lo tenemos disponible para su descarga. Lo más cómodo es descargar el código fuente del ejemplo anterior () y editar los aspectos que se indican en este tutorial.