Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / Proyectos / MVC Java y Base de Datos Tutorial

MVC Java y Base de Datos Tutorial

Autor jc mouse sábado, agosto 25, 2012

En post pasados [Ejemplo práctico de MVC java Swing con Netbeans3 en raya java con MVC y NetbeansMVC: Modelo, Vista y Controlador en PHP], se vio una introducción y algunos ejemplos sobre el modelo MVC (Model, View, Controller). En esta ocasión, no volveremos repetir en que consiste tal patrón, sino realizaremos un ejemplo práctico, creo yo, es la mejor forma de aprender y familiarizarse con este modelo para el desarrollo de software.

No hacemos uso de ningún framework, al contrario, todo el proyecto se desarrolla sin ellos, para asi entender de lleno como es que trabaja el modelo MVC .

Necesitamos

  • IDE Netbeans 6.9 o superior
  • Una base de datos MySQL
  • Conector JDBC Java/MySQL
  • Conocimiento intermedio sobre lenguaje  SQL y Java

Nivel: Intermedio

Duración: 3o minutos

Comencemos.

1.- Lo primero que necesitamos es una base de datos, créala con el nombre de tu preferencia. Para este ejemplo se utiliza solamente una tabla – Nombre: Producto – cuya estructura es la siguiente:

CREATE TABLE producto (
  p_id varchar(6) NOT NULL,
  p_nombre varchar(21) NOT NULL,
  p_precio float NOT NULL default '0',
  p_cantidad int(20) NOT NULL default '0',
  PRIMARY KEY  (p_id)
)

Insertamos unos cuantos datos:

INSERT INTO producto VALUES ('P9-U7J', 'Producto 1', 100, 0);
INSERT INTO producto VALUES ('KO-8HY', 'Producto 2', 56.9, 0);
INSERT INTO producto VALUES ('UJ-9KK', 'Producto 3', 120.5, 0);
INSERT INTO producto VALUES ('KK-77G', 'Producto 4', 23.4, 0);
INSERT INTO producto VALUES ('KJ-886', 'Producto 5', 88, 0);
INSERT INTO producto VALUES ('PP-99P', 'Producto 6', 78.9, 0);
INSERT INTO producto VALUES ('GH-77U', 'Producto 7', 99.9, 0);

2.- Abre Netbeans y crea un nuevo proyecto de escritorio y dale un nombre, por ejemplo “AProductoMVC”. Netbeans te crea la siguiente estructura de archivos:

AProductoMVC
-Paquete de fuentes
-- aproductomvc
----Main.Java
-Paquete de fuentes
-Bibliotecas
-Bibliotecas de pruebas

3.- Lo que haremos ahora sera crear nuestra estructura MVC.

En el paquete donde se encuentra el Main.java, clic derecho -> Reestructurar -> Cambiar nombre. Coloca como nuevo nombre “controlador” y clic en “reestrcututar”.

Crea dos nuevos paquetes más, “modelo” y “vista”.

En el paquete controlador, agrega una nueva clase llamada “controlador.java”.

En el paquete modelo, agrega dos clases que son, “database.java” y “modelo.java”.

En el paquete vista,  añade un JFrame que se llamara “interfaz.java”.

Como cambiamos el nombre a nuestro paquete donde estaba el Main.al ejecutar nos saldrá un error “java.lang.NoClassDefFoundError: aproductomvc/Main”, esto nos dice que no encuentra el Main. Para darle solución, clic derecho sobre el proyecto -> Propiedades. Busca la categoría “Ejecutar”  y en la opción del Main Class , dale clic en examinar y selecciona “controlador.main” , para terminar clic en “aceptar”.

4.- Como hacemos uso de una base de datos,  debemos añadir al proyecto el Driver MySQL JDBC en su última versión.

Hasta ahora debemos tener lo siguiente:

proyecto java

5.- LA VISTA: Nuestro proyecto consta de tan solo un JFrame con el siguiente diseño:

diseño interfaz

Estamos utilizando “jformattedtextfield” para tratar los datos, las mascaras son las siguientes:

__id_producto : AA-AAA

__nombre: *********************

__precio: #0.00

__cantidad: #0

IMPORTANTE: Netbeans crea por defecto estos controles con la propiedad PRIVATE, esto no nos sirve, debemos cambiarlo, selecciona un control (por ejemplo: __id_producto ), dale clic derecho y busca “propiedades”, en la pestaña “Codigo”, cambia la propiedad “modificadores de variable: private”, por PUBLIC. Repite esta acción para todos los controles.

6. EL MODELO: aquí colocamos la representación de nuestro sistema, puede ser una sola clase o varias clases dependiendo del tamaño de nuestro proyecto. En este tutorial, se utilizan dos clases podrían ser más o menos depende del programador.

Clase “database“, nos conectara a MySQL y retornara la conexión.

package modelo;
import java.sql.*;
/**
 * @web http://www.jc-mouse.net
 * @author Mouse
 */
public class database {
 /* DATOS PARA LA CONEXION */
  /** base de datos por defecto es test*/
  private String db = "dbtest";
  /** usuario */
  private String user = "root";
  /** contraseña de MySql*/
  private String password = "";
  /** Cadena de conexion */
  private String url = "jdbc:mysql://localhost/"+db;
  /** variable para trabajar con la conexion a la base de datos */
  private Connection conn = null;

   /** Constructor de clase */
   public database(){
        this.url = "jdbc:mysql://localhost/"+this.db;
       try{
         //obtenemos el driver de para mysql
         Class.forName("com.mysql.jdbc.Driver");
         //obtenemos la conexión
         conn = DriverManager.getConnection( this.url, this.user , this.password );         
      }catch(SQLException e){
         System.err.println( e.getMessage() );
      }catch(ClassNotFoundException e){
         System.err.println( e.getMessage() );
      }
   }

   public Connection getConexion()
   {
    return this.conn;
   }

}

Clase modelo.java , aquí es donde se procesa la información y retorna un resultado.

package modelo;
import java.sql.*;
import javax.swing.table.DefaultTableModel;
/**
 * @web http://www.jc-mouse.net
 * @author Mouse
 */
public class modelo extends database{

    /** Constructor de clase */
    public modelo (){}

    /** Obtiene registros de la tabla PRODUCTO y los devuelve en un DefaultTableModel*/
    public DefaultTableModel getTablaProducto()
    {
      DefaultTableModel tablemodel = new DefaultTableModel();
      int registros = 0;
      String[] columNames = {"ID","Nomnbre","Precio","Cantidad"};
      //obtenemos la cantidad de registros existentes en la tabla y se almacena en la variable "registros"
      //para formar la matriz de datos
      try{
         PreparedStatement pstm = this.getConexion().prepareStatement( "SELECT count(*) as total FROM producto");
         ResultSet res = pstm.executeQuery();
         res.next();
         registros = res.getInt("total");
         res.close();
      }catch(SQLException e){
         System.err.println( e.getMessage() );
      }
    //se crea una matriz con tantas filas y columnas que necesite
    Object[][] data = new String[registros][5];
      try{
          //realizamos la consulta sql y llenamos los datos en la matriz "Object[][] data"
         PreparedStatement pstm = this.getConexion().prepareStatement("SELECT * FROM producto");
         ResultSet res = pstm.executeQuery();
         int i=0;
         while(res.next()){
                data[i][0] = res.getString( "p_id" );
                data[i][1] = res.getString( "p_nombre" );
                data[i][2] = res.getString( "p_precio" );
                data[i][3] = res.getString( "p_cantidad" );
            i++;
         }
         res.close();
         //se añade la matriz de datos en el DefaultTableModel
         tablemodel.setDataVector(data, columNames );
         }catch(SQLException e){
            System.err.println( e.getMessage() );
        }
        return tablemodel;
    }

    /** Registra un nuevo producto */
    public boolean NuevoProducto(String id, String nombre , String precio, String cantidad)
    {
        if( valida_datos(id, nombre, precio, cantidad) )
        {
            //se reemplaza "," por "."
            precio = precio.replace(",", ".");
            //Se arma la consulta
            String q=" INSERT INTO producto ( p_id , p_nombre , p_precio, p_cantidad ) "
                    + "VALUES ( '" + id + "','" + nombre + "', '" + precio + "'," + cantidad + " ) ";
            //se ejecuta la consulta
            try {
                PreparedStatement pstm = this.getConexion().prepareStatement(q);
                pstm.execute();
                pstm.close();
                return true;
            }catch(SQLException e){
                System.err.println( e.getMessage() );
            }
            return false;
        }
        else
         return false;
    }

    /** Elimina un registro dado su ID -> Llave primaria */
    public boolean EliminarProducto( String id )
    {
         boolean res=false;
        //se arma la consulta
        String q = " DELETE FROM producto WHERE p_id='" + id + "' " ;
        //se ejecuta la consulta
         try {
            PreparedStatement pstm = this.getConexion().prepareStatement(q);
            pstm.execute();
            pstm.close();
            res=true;
         }catch(SQLException e){
            System.err.println( e.getMessage() );
        }
        return res;
    }

    /** Metodo privado para validar datos */
    private boolean valida_datos(String id, String nombre , String precio, String cantidad)
    {
        if( id.equals(" - ") )
            return false;
        else if( nombre.length() > 0 && precio.length()>0 && cantidad.length() >0)
        {
            return true;
        }
        else return false;
    }

}

7.- EL CONTROLADOR: es el encargado de captutar los eventos producidos por el usuario procesarlos enviando los datos al modelo y retornar la información en la vista.

package controlador;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
//se importa modelo e interfaz
import modelo.modelo;
import vista.interfaz;
/**
 * @web http://www.jc-mouse.net
 * @author Mouse
 */
public class controlador implements ActionListener,MouseListener{

    /** instancia a nuestra interfaz de usuario*/
    interfaz vista ;
    /** instancia a nuestro modelo */
    modelo modelo = new modelo();

    /** Se declaran en un ENUM las acciones que se realizan desde la
 * interfaz de usuario VISTA y posterior ejecución desde el controlador
 */
    public enum AccionMVC
    {
        __VER_PRODUCTOS,
        __AGREGAR_PRODUCTO,
        __ELIMINAR_PRODUCTO
    }

    /** Constrcutor de clase
 * @param vista Instancia de clase interfaz
 */
    public controlador( interfaz vista )
    {
        this.vista = vista;
    }

    /** Inicia el skin y las diferentes variables que se utilizan */
    public void iniciar()
    {
        // Skin tipo WINDOWS
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            SwingUtilities.updateComponentTreeUI(vista);
            vista.setVisible(true);
        } catch (UnsupportedLookAndFeelException ex) {}
          catch (ClassNotFoundException ex) {}
          catch (InstantiationException ex) {}
          catch (IllegalAccessException ex) {}

        //declara una acción y añade un escucha al evento producido por el componente
        this.vista.__VER_PRODUCTOS.setActionCommand( "__VER_PRODUCTOS" );
        this.vista.__VER_PRODUCTOS.addActionListener(this);
        //declara una acción y añade un escucha al evento producido por el componente
        this.vista.__AGREGAR_PRODUCTO.setActionCommand( "__AGREGAR_PRODUCTO" );
        this.vista.__AGREGAR_PRODUCTO.addActionListener(this);
        //declara una acción y añade un escucha al evento producido por el componente
        this.vista.__ELIMINAR_PRODUCTO.setActionCommand( "__ELIMINAR_PRODUCTO" );
        this.vista.__ELIMINAR_PRODUCTO.addActionListener(this);

        //añade e inicia el jtable con un DefaultTableModel vacio
        this.vista.__tabla_producto.addMouseListener(this);
        this.vista.__tabla_producto.setModel( new DefaultTableModel() );
    }

    //Eventos que suceden por el mouse
    public void mouseClicked(MouseEvent e) {
        if( e.getButton()== 1)//boton izquierdo
        {
             int fila = this.vista.__tabla_producto.rowAtPoint(e.getPoint());
             if (fila > -1){                
                this.vista.__id_producto.setText( String.valueOf( this.vista.__tabla_producto.getValueAt(fila, 0) ));
                this.vista.__nombre.setText( String.valueOf( this.vista.__tabla_producto.getValueAt(fila, 1) ));
                this.vista.__precio.setText( String.valueOf( this.vista.__tabla_producto.getValueAt(fila, 2) ));
                this.vista.__cantidad.setText( String.valueOf( this.vista.__tabla_producto.getValueAt(fila, 3) ));
             }
        }
    }

    public void mousePressed(MouseEvent e) {}

    public void mouseReleased(MouseEvent e) {}

    public void mouseEntered(MouseEvent e) {}

    public void mouseExited(MouseEvent e) { }

    //Control de eventos de los controles que tienen definido un "ActionCommand"
    public void actionPerformed(ActionEvent e) {

    switch ( AccionMVC.valueOf( e.getActionCommand() ) )
        {
            case __VER_PRODUCTOS:
                //obtiene del modelo los registros en un DefaultTableModel y lo asigna en la vista
                this.vista.__tabla_producto.setModel( this.modelo.getTablaProducto() );
                break;
            case __AGREGAR_PRODUCTO:
                //añade un nuevo registro
                if ( this.modelo.NuevoProducto(
                        this.vista.__id_producto.getText(),
                        this.vista.__nombre.getText() ,
                        this.vista.__precio.getText(),
                        this.vista.__cantidad.getText() ) )
                {
                    this.vista.__tabla_producto.setModel( this.modelo.getTablaProducto() );
                    JOptionPane.showMessageDialog(vista,"Exito: Nuevo registro agregado.");
                    this.vista.__id_producto.setText("");
                    this.vista.__nombre.setText("") ;
                    this.vista.__precio.setText("0");
                    this.vista.__cantidad.setText("0") ;
                }
                else //ocurrio un error
                    JOptionPane.showMessageDialog(vista,"Error: Los datos son incorrectos.");
                break;
            case __ELIMINAR_PRODUCTO:
                if ( this.modelo.EliminarProducto( this.vista.__id_producto.getText() ) )
                {
                    this.vista.__tabla_producto.setModel( this.modelo.getTablaProducto() );
                    JOptionPane.showMessageDialog(vista,"Exito: Registro eliminado.");
                    this.vista.__id_producto.setText("");
                    this.vista.__nombre.setText("") ;
                    this.vista.__precio.setText("0");
                    this.vista.__cantidad.setText("0") ;
                }
                break;       
        }
    }

}

8.- Para terminar el código para el Main.java, el encargado de arrancar toda la aplicación.

package controlador;
import vista.interfaz;
/**
* @web http://www.jc-mouse.net/
 * @author Mouse
 */
public class Main {

    public static void main(String[] args) {
        //ejecuta el controlador y este la vista
        new controlador( new interfaz() ).iniciar() ;
    }

}

Proyecto en ejecución

MVC project GUI

Descarga el proyecto en netbeans 6.9 AQUI

Tags

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Crea un Tabbed Activity desde cero

Crea un Tabbed Activity desde cero

Un Tabbed Activity te permite cambiar la vista entre  fragmentos desplazando el dedo  de izquierda a derecha o de derech...

Rompecabezas [Código Fuente]

Rompecabezas [Código Fuente]

Hace tiempo me pidieron el código fuente de un juego de Puzzle de Neon Genesis Evangelión, este juego es completo, tiene...

Modificar las pestañas de JTabbedPane

Modificar las pestañas de JTabbedPane

En este tutorial veremos lo fácil que es personalizar las pestañas de un JTabbedPane con unas cuantas lineas de código y...

Primeros pasos en Jaspersoft Studio

Primeros pasos en Jaspersoft Studio

¿Que es Jaspersoft Studio? Jaspersoft Studio es el nuevo diseñador de informes basado en Eclipse para JasperReports y Ja...

Método de la Regla Falsa o Regula Falsi

Método de la Regla Falsa o Regula Falsi

Este método, también conocido como método de interpolación lineal, es un método iterativo de resolución numérica de ecua...

Puzzle en Visual Basic [Código Fuente]

Puzzle en Visual Basic [Código Fuente]

Rompecabezas 3×3 realizado en Visual Basic .NET, lo que se hizo fue una migración de un proyecto hecho en java (pue...

9 comentarios en “MVC Java y Base de Datos Tutorial”

  1. Carlos dice:

    Primeramente felicitarte por ayudarnos a aprender .. muchas gracias

    Tengo unas preguntas para desarrollar un programa que este instalado en varios equipos y todos accedan a mi base de datos ..

    – Tengo que crear una conexion a la base de datos por cada usuario ?
    – Tengo que trabajar con un Pool de conexiones ?
    – Tengo que Abrir y cerrar conexion a la base de datos por cada actualizacion de mi BD?

    Te lo agradeceria si me pudieras orientar en estos puntos

    MUchas gracias y adelante

    1. Mouse dice:

      respondiendo:
      la respuesta que te daré puede que sea muy ambigua pero bueno, aquí esta “DEPENDE” 🙂
      ya abras buscado información en internet y te darás cuenta de que hay mas de una forma de hacer cada cosa que dices y repito 🙂 “depende”, puedes hacer uso de como dices POOL (agrupamiento de conexiones) o abrir/cerrar una conexión nueva cada vez que se requiera, supongo que tu aplicación es de escritorio para una intranet, el trafico no es muy grande, digamos ¿200 personas? y no todas se conectan al mismo tiempo.

      1. Carlos dice:

        La verdad no se cual usar mi aplicaciones tengra al rededor de 200 usuario …
        mi pregunta era cual es lo mas optimo o si fuera posible toques este tema mas adelante
        Yo vi en unas aplicaciones que se crea un conexion a la base de datos por cada usuario y se le da permisos de insercion …
        Otra es trabajar con una sola conexion por lo cual tendria que estar conectandome y desconectandome por cada usuario …
        Y todo lo que te momento lo estuve lleyendo … y recurria a tu ayuda para que si tal vez sea uno de tus proximos post ..

        Muchas gracias … en verdad lo que estas haciendo es lo maximo … continua asi … muchos exitos

        1. Mouse dice:

          por eso, depende de la cantidad de usuarios que hagan uso del sistema , si son pocos da igual cualquier método que utilices ya que la ganancia seria en milisegundos y bueno no creo que la gente se queje porque su consulta tardo 0.05 milisegundos mas de lo esperado o.O

          Mega abrió ayer y fueron tantas las consultas ( miles o millones de usuarios conectados al mismo tiempo ) que sus servidores dejaron de funcionar creo que unas horas, yo no podía subir ni 20 kb 🙂

          1. Fred dice:

            siiiiiiiii has un tutorial sobre privilegios amigo, mira yo tengo una idea y mas bien lo vi de otro programa mas no lo supe implementar en el mio, consiste en una tabla donde van a estar todos los usuarios, se pide nombre de usuario, contraseña y por ejemplo nivel o tipo en nivel o tipo se coloca cero o uno, donde cero es administrador y uno vendedor, en este realiza una consulta a la base de datos para ver de que tipo es si es cero se abre la interfaz con todas las opciones disponibles y si es uno se abre la interfaz con limitaciones de opciones es decir hay dos interfaz uno para administrador y otro para vendedor pero no me sale a la hora de tratar de implementarlo en mi programa =S.

          2. Mouse dice:

            existen dos tipos de privilegios en aplicaciones con base de datos, los que se dan a nivel de base de datos y a nivel de aplicación, el primero se asignan permisos a los usuarios “de la base de datos” en INSERT, UPDATE, DELETE y el segundo, el que citas es mas fácil de implementar y hay muchas maneras de hacerlo, en el ejemplo que das, usar dos interfaces para cada tipo de usuario no me parece optimo ya que si quieren hacer alguna modificación, deberás trabajar el doble (en ambas interfaces), lo mejor, creo yo, es utilizar permisos y ya sea denegar el acceso a cierto tipo de interfaz o evitar el registro o borrado de ciertos datos según el nivel del usuario logueado 🙂

  2. juan dice:

    Hola amigo tendras de casualidad un tutorial de spring, jsf porque estoy tratando de aprender esos frameworks por mi cuenta, saludos

  3. Angel dice:

    Amigo muy buen tutorial he analizado todo el codigo, estoy implementado un cuadro de login donde un usuario debe autenticarse primero, seguí la misma estructura que tú tienes (en controlador y modelo). Pero no me funciona cuando le doy “Aceptar” no me autentica el usuario, hay algo que debo hacer en la vista? La unica parte que no entiendo es como se envía la opción al public enum AccionMVC desde la vista

    De antemano muchas gracias

  4. jimmy dice:

    muy buen tutorial es excelente gracias men eres un genio me ha servido mucho tu tutorial

Los comentarios están cerrados para este post
Comparte lo que sabes

Categorias

Últimas entradas

Secret (https://getsecret.now.sh/) es una aplicación web gratuita que te permite enviar mensajes temporales cifrados que...

PHPUnit es un framework que se utiliza para escribir tests en PHP, Netbeans nos permite configurarlo y usarlo fácilmente...

Una Prueba Unitaria, es una forma de comprobar que nuestro código, hace lo que se supone debe hacer; es decir, se asegur...

La prueba del camino básico, es una prueba de “caja blanca” que consiste en verificar el código de nuestros...

Android Bolivia

Bandera en Alto