Java y MySQL

Desarrollo de aplicaciones de escritorio en Java y MySQL.

Para poder desarrollar la aplicaciones en esta unidad necesitamos el siguiente software:

Conexion a la base de datos con phpmyadmin o con Workbench

Entorno de Java SDK

Base de datos MySQL

Admnistrador de base de datos: phpmyadmin (necesario instalar Apache y MySQL, opcionalmente PHP, para windows se puede usar WAMP "Windows Apache MySQL Php", en LINUX es LAMP "Linux Apache MySQL Php" ó Workbench que no requiere el servidor Apache solo MySQL (mariaDB).

Frame para desarrollo: NetBeans  ó  Eclipse

Ejemplo de conexion a MySQL:

Para ello usamos phpmyadmin para iniciar MySQL (Maria DB),






crearemos una bsase de datos llamada "Escuela"


con una tabla simple que se llamara "persona"


 con los siguientes campos:



Previsualizar el comando SQL:



Al ejecutar la secuencia de SQL:



Agregamos unos datos para la prueba que nos ocupa:

Usaremos la pestaña llamada Insertar:





Despúes de hacer un clic en el botón Continuar agregara 2 filas a la tabla:



Al terminar con el boton Continuar, usamos la pestaña examinar



Con esto podemos trabajar a manera de ejemplo.

Proseguimos con NetBeans para crear con un frame el ejemplo con un botón para la consulta de la base de datos.

Iniciamos co una nueva aplicacion en: Java---> Java Aplication



Le establecemos el nombre como SQL, y no creamos la clase principal (se retira la marca Create Main Class):



Al formarse el proyecto se vera de la siguiente forma:



En la sección Libraries (Bibliotecas) realizamos un clic con el botón derecho, mostrando una lista de elementos y seleccionamos Add Library ...    buscamos MySQL JDBC Driver que es el conector entre JAVA y MySQL, es indispensable para poder leer, escribir información en MySQL.

(si se usa Eclipse debera de agregarese el conector de forma manual, buscando el conector en internet, y descargarlo, e indicar en donde se localizara para poder usarlo)



Solo queda por hacer clic en Add Library...  y se observara dfe la siguiente forma:


Se crea un paquete en Source package ...  hacer un clic botón derecho y seleccionar New -> Java Package ...




Se le establece el nombre como app, hacemos clic en Finish....



Agregamos un Nuevo Formulario de JFrame. Form....



Lo que la llamaremos conexion




A lo cual genera el frame para agregar botones, cuadros, etc en el, del lado derecho tenemos los controles para usar en el frame usamos  Button, se cambia el nombre del botón a Conexion, con Edit Text, y cambaiamos la variable asociada al botón como btnConexion (recuerdese la unidad anterior SWING):

Ve aqui el proceso

Ahora realizamos la programacion para que este botón al activarse se conecte con SQL, para entrar el código generado se hace un doble clic en el botón que formamos y véremos el código generado aqui, lo que se va a realizar es la programación para indicar la base de datos el nombre de la tabla y los campos a usar, esto no se puede realizar con el frame.

Agregamos la siguientes lineas en el constructor:

// constructor
public class conexion extends javax.swing.JFrame {

    public static final String URL = "jdbc:mysql://localhost:3306/Escuela"; // el lugar donde se tomaran los datos jdbc (Java DataBase Connectivity)
                                                                                                                    // mysql Sistema de base de datos MySQL
                                                                                                                    // localhost:3306 el servidor local accediendo por el puerto 3306
                                                                                                                    // Escuela el nombre de la base de Datos 
    public static final String USERNAME = "root";                                     // el usuario de la base de datos
    public static final String PASSWORD = "xxxxxx";                              // xxxxx contraseña para acceso a la BD y la tabla

Hacemos el método para la consulta de los datos a la base de datos, habremos de explicar la linea que tiene el método JOptionPane.showMessageDialog(null,"Conexion exitosa")

El método showMessageDialog tiene 3 sobrecargas del método, uno que recibe 2 parametros, otro de  4, y otro de 5, y vamos personalizando cada vez más nuestro mensaje, el primero que veremos es el de dos parametros:

JOptionPane.showMessageDialog(null,"Operacion realizada correctamente")

El primer parámetro, representa el componente padre sobre el cual el mensaje se mostrará, si nosotros no le enviamos ninguno, como en este caso lo estamos haciendo, simplemente mostrará una ventana



Si  le enviamos un componente, se colocará encima de el, sin ninguna variación en el funcionamiento, el segundo parámetro obviamente, es el mensaje que queremos observar, y listo, un mensaje fácil de hacer, bien, ahora veamos otra cosa, el anterior fue el método con dos parámetros, ahora bien, cuando utilizamos el método de cuatro parámetros tenemos un poco más de personalización.

JOptionPane.showMessageDialog(null, "Mensaje dentro de la ventana", "Mensaje en la barra de titulo", JOptionPane.WARNING_MESSAGE);

El funcionamiento de este método es un poco diferente, pero más útil:


Primer Parámetro: El componente padre sobre el cual se mostrará la ventana de dialogo.

Segundo Parámetro: El mensaje que se mostrará dentro de la ventana.

Tercer Parámetro: El mensaje que se mostrará en la barra de titulo.

Cuarto Parámetro: Una variable Int contenida por JOptionPane, que representa el icono que se mostrará en la ventana, algunos de los valores posibles son: INFORMATION_MESSAGE , WARNING_MESSAGE , QUESTION_MESSAGE , PLAIN_MESSAGE, ERROR_MESSAGE

En el caso anterior, el mensaje se vería de esta manera (hay un mensaje en el titulo  si no es visible aumenta el brillo del monitor):



Al usar un WARNING_MESSAGE se presenta con un icono de alerta.

para más información de este método y mas en:

https://serprogramador.es/programando-mensajes-de-dialogo-en-java-parte-1/


Sigamos con la consulta:

public static Connection getConection()
    {
      Connection con = null; //iniciamos la variable con
//inicia la transaccion
      try{
          Class.forName("com.mysql.jbdc.Driver"); //uso conector java-sql
          con = (Connection) DriverManager.getConnection(URL, USERNAME, PASSWORD); // realiza la conexion y se asigna a la variable con
          // el (Connection) es un cast para realizar la conexion, revisar que es el cast
          JOptionPane.showMessageDialog(null,"Conexion exitosa");
         
      }catch(Exception e){
        System.out.println(e);
      }  // este procedimiento es para la conexion
        return null;
    }// termina el procedimiento Connection
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

Debemos importar una biblioteca, para este método, deberá estar despúes de package app, parte superior del programa : package app;


import com.mysql.jdbc.Connection;

Ahora haremos el procedimieto para el botón (al hacer clic en el, se ejecuta el codigo), antes dáremos una introduccion al PreparedStatement

Cuando trabajamos con una base de datos es posible que haya sentencias SQL que tengamos que ejecutar varias veces durante la sesión, aunque sea con distintos parámetros. Por ejemplo, durante una sesión con base de datos podemos querer insertar varios registros en una tabla. Cada vez los datos que insertamos serán distintos, pero la sentencia SQL será la misma: Un INSERT sobre determinada tabla que será simpre igual, salvo los valores concretos que queramos insertar.
Casi todas las bases de datos tienen previsto un mecanismo para que en estos casos la ejecución de esas sentencias repetidas sea más rápida. Si tenemos una tabla person con un id, una edad, un nombre, un apellido y hacemos, por ejemplo, varios INSERT así


mysql> INSERT INTO person VALUES (null, 23, 'Pedro', 'Perez');

mysql> INSERT INTO person VALUES (null, 33, 'Rodrigo', 'Rodriquez');


En cada caso la base de datos deberá analizar la sentencia SQL, comprobar que es correcta, convertir los datos al tipo adecuado (por ejemplo, los enteros a int) y ejecutar la sentencia.
El mecanismo que preven las bases de datos para hacer más eficiente este proceso es que le indiquemos, previamente, el tipo de sentencia que vamos a usar, de forma que la base de datos la "precompila" y la guarda en condiciones de ser ejecutada inmediatamente, sin necesidad de analizarla en cada caso. Esto es lo que se conoce como una prepared statement. En el caso de mysql, se haría de esta forma:

mysql> PREPARE INSERT FROM "INSERT INTO persona VALUES (null, ?, ?, ?)";
mysql> SET @edad=23;
mysql> SET @nombre='Pedro';
mysql> SET @apellido='Perez';
mysql> EXECUTE insertar USING @edad,@nombre,@apellido
mysql> SET @edad=33;
mysql> SET @nombre='Rodrigo';
mysql> SET @apellido='Rodriguez';
mysql> EXECUTE insertar USING @edad,@nombre,@apellido;
mysql> DEALLOCATE PREPARE insertar;

donde hemos preparado una PreparedStatement de nombre insertar con la SQL del INSERT, en la que hemos reemplazado los valores concretos por interrogantes. Vease que no hemos puesto comillas entre los interrogantes. Hemos hecho dos inserciones dando valores a unas variables @edad, @nombre y @apellido, que son las que se usarán en el EXCECUTE de la PreparedStatement. Una vez finalizadas las inserciones, avisamos a la base de datos que no vamos a usar más esta PreparedStatement con un DEALLOCATE.

Si la base de datos soporta PreparedStatement y el driver/conector que usemos para hablar con esa base de datos desde java los soporta también, entonces podemos usar los PreparedStatement desde java.
Si la base de datos no los soporta o el driver/conector no los soporta, podemos desde java hacer el código igualmente. A la hora de codificar podemos usar los PreparedStatement independientemente de que la base de datos y/o el conector los soporten o no, pero no conseguiremos los beneficios deseados. Aunque usemos PreparedStatement desde java, por debajo acabarán traduciéndose a statement normal. Si quieres asegurarte de conseguir todos los beneficios, debes verificar si tu base de datos y el driver de conexión con ella soportan los prepared statement. En el caso de MySQL, las versiones modernas lo hacen.


Lo primero de todo es establecer la conexión. En el caso de MySQL debemos además poner un pequeño parámetro adicional para configurar el driver para que use las prepared statement en el servidor. Este parámetro es useServerPrepStmts=true, por lo que la cadena de conexión completa sería

try {
   Class.forName("com.mysql.jdbc.Driver");

   // Es necesario useServerPrepStmts=true para que los PreparedStatement
   // se hagan en el servidor de bd. Si no lo ponemos, funciona todo
   // igual, pero los PreparedStatement se convertirán internamente a
   // Statements.
   Connection conexion = DriverManager.getConnection(
      "jdbc:mysql://servidor/basedatos?useServerPrepStmts=true",
      "usuario", "password");
   ...
} catch (Exception e) {
   e.printStackTrace();
}

para mas información revise: http://www.chuidiang.org/java/mysql/PreparedStatement-java-mysql.php


  private void btnConexionActionPerformed(java.awt.event.ActionEvent evt) {                                           
       try{
         Connection con = null;
         con = getConection();  //solicitamos el procedimiento de la conexion
        
         PreparedStatement ps; // Es una declaración SQL se precompila y se almacena en un objeto PreparedStatement. Este objeto se puede usar para ejecutar
                                             // esta  declaración de manera eficiente varias veces.
         ResultSet res;              //obtener los valores devueltos por la consulta
        
         ps = con.prepareStatement("SELECT * FROM persona");
         res = ps.executeQuery();
        
         if(res.next()){ //solo extrae la primer fila
             JOptionPane.showMessageDialog(null, res.getString("Nombre")+" "+ res.getString("Domicilio"));
         } else {
             JOptionPane.showMessageDialog(null,"No existen datos");
         }
        
         con.close();
        
       }catch(Exception e){
        System.out.println(e);  
       }
      
    }                

Excepciones, o sencillamente problemas.

En la programación siempre se producen errores, más o menos graves, pero que hay que gestionar y tratar correctamente. Por ello en java disponemos de un mecanismo consistente en el uso de bloques try/catch/finally. La técnica básica consiste en colocar las instrucciones que podrían provocar problemas dentro de un bloque try, y colocar a continuación uno o más bloques catch, de tal forma que si se provoca un error de un determinado tipo, lo que haremos será saltar al bloque catch capaz de gestionar ese tipo de error específico. El bloque catch contendrá el codigo necesario para gestionar ese tipo específico de error. Suponiendo que no se hubiesen provocado errores en el bloque try, nunca se ejecutarían los bloques catch.


El resultado de este proceso es :

Resultado consulta en MySQL

Y aqui todo el codigo del programa para realizar consultas en MySQL. (recuerde que mucho del codigo aqui visto lo genera el frame tal como se hace con la biblioteca Swing)

package app;

import com.mysql.jdbc.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.swing.JOptionPane;
// constructor
public class conexion extends javax.swing.JFrame {
public static final String URL = "jdbc:mysql://localhost:3306/Escuela";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "xxxxx";   
   
    public conexion() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        btnConexion = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        btnConexion.setText("Conexion");
        btnConexion.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConexionActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(153, 153, 153)
                .addComponent(btnConexion)
                .addContainerGap(172, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(118, 118, 118)
                .addComponent(btnConexion)
                .addContainerGap(154, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                       

    private void btnConexionActionPerformed(java.awt.event.ActionEvent evt) {                                           
           try{
         Connection con = null;
         con = getConection();
       
         PreparedStatement ps;
         ResultSet res;
       
         ps = con.prepareStatement("SELECT * FROM persona");
         res = ps.executeQuery();
       
         if(res.next()){ //solo extrae la primer fila
             JOptionPane.showMessageDialog(null, res.getString("Nombre")+" "+ res.getString("Domicilio"));
         } else {
             JOptionPane.showMessageDialog(null,"No existen datos");
         }
       
         con.close();
       
       }catch(Exception e){
        System.out.println(e); 
       }
    }                                          

  public static Connection getConection()
    {
      Connection con = null; //iniciamos la variable con.
      try{
          Class.forName("com.mysql.jdbc.Driver"); //uso conector java-sql
          con = (Connection) DriverManager.getConnection(URL, USERNAME, PASSWORD); // realiza la conexion y se asigna a la variable con
          // el (Connection) es un cast para realizar la conexion, revisar que es el cast
          JOptionPane.showMessageDialog(null,"Conexion exitosa");
        
      }catch(Exception e){
        System.out.println(e);
      }  // este procedimiento es para la conexion
        return con;
    
    }// termina el procedimiento Connection
 
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(conexion.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(conexion.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(conexion.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(conexion.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new conexion().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                    
    private javax.swing.JButton btnConexion;
    // End of variables declaration                  
}


CRUD

Create - Crear

Read - Leer

Update - Actualizar

Delete - Eliminar

Para realizar este procedimiento modificaremos la base de datos que habíamos creado anteriormente, la base de datos llamada Escuela, y agregaremos un campo mas a la tabla persona, que es campo llamado clave varchar(10) y sera debajo del campo Id, véase las opciones a usar.

Proceso para agregar un campo a la tabla

Vemos que hemos colocado el campo clave en su primer letra en minusculas, prara demostrar lo practico de phpmyadmin cambaire de minuscula a mayuscula y despúes agregaremos directamente a la tabla el dato, con el mismo phpmyadmin:

Modificar campo e introducir datos

Realizamos un nuevo proyecto, donde crearemos un formulario usando JFrame, y tomando del lado derecho en la seccion Swing Controls

Nuevo proyecto con JFrame

En el área formada  de JFrame  agregaremos una etiqueta para identificar el campo que esta en la tabla de la base de datos Escuela.




Del lado derecho seleccionamos Label y lo pasamos al área de JFrame editamos el texto, le colocamos el texto Clave: después agregamos una caja de texto con el control Text Field editamos el nombre de la variable a txtClave para relacionarla con el campo de la base de datos, se demostrara para el primer elemento que es el campo Clave, los siguientes campos los realizaras tu.

Ejemplo de Formulario.



Ahora pdemos realizar un cambio, en Genero lo haremos con un ComboBox:

Primero marque el cuadro al lado derecho de la etiqueta Genero, y borrela con la tecla Supr que hemos formado, seleccionamos el control Swing de ComboBox, revise el lado derecho de la siguente imagen:



Arrastre el control al la parte derecha del la etiqueta Genero:



Hagamos la secuencia para los items:

Agregar Items a ComboBox

Nota: si por alguna accion equivocada borramos la paleta del aado derecho o cualquier ventana, podemos restablecer las totalidad de las ventanas usando la opcion Window -> Reset Windows, con ello regresan todas la ventanas del área de trabajo que estan por defecto.

Agregar botones para control de las acciones en la base de datos crearemos los botones: Guarda Modifica Eliminar Limpiar

Agregar botones de control

Agregaremos mas botones uno para la busqueda de los datos de la tabla, y un cuadro de texto para observar el Id, este es automatico y no es posible cambiarlo solo será mostrado:

Agregar boton de busqueda

Para continuar y comenzar la programacion necesitamos agregar el proceso de conexion a la base de datos, usamos las mismas instrucciones que el proyecto anterior, para pasar al codigo y viceversa usamos los paneles de Source y Design:



lo que esta marcado en rojo es el codigo a agregar al codigo del actual proyecto


package app;

import com.mysql.jdbc.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.swing.JOptionPane;
import java.sql.Date;


// constructor
public class conexion extends javax.swing.JFrame {

    public static final String URL = "jdbc:mysql://localhost:3306/Escuela";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "xxxx";   
   
    public conexion() {
        initComponents();
    }





----------------------------------------------------------- (las siguientes lineas debéran estar antes de main() ----------------------------------------------------------
public static Connection getConection()
    {
      Connection con = null; //iniciamos la variable con inicia la transaccion
      try{
          Class.forName("com.mysql.jbdc.Driver"); //uso conector java-sql
          con = (Connection) DriverManager.getConnection(URL, USERNAME, PASSWORD); // realiza la conexion y se asigna a la variable con
          // el (Connection) es un cast para realizar la conexion, revisar que es el cast
          JOptionPane.showMessageDialog(null,"Conexion exitosa");
         
      }catch(Exception e){
        System.out.println(e);
      }  // este procedimiento es para la conexion
        return null;
    }// termina el procedimiento Connection
    /**
     * @param args the command line arguments
     */

Para activar los codigos de cada botón realiza un doble clic sobre el botón en el diseño, con ello se mostraran en el panel del lado  izquierdo.

Activar codigo de botones

Pasamos al codigo del botón Guardar:

Para realizar esto, es buscar en todo el codigo y localizar la instrucción del botón, y realizarlo con el panel del lado izquierdo ubicando el procedimiento:

Como seleccionar elementos desde el panel izquierdo

Para el efecto que requerimos de agregar datos es necesario indicar como se va a realizar la acción de Guardar (vease el codigo en rojo)



    public static final String URL = "jdbc:mysql://localhost:3306/Escuela";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "uss1707";
   
    PreparedStatement ps; // preparar la instruccion para insertar datos
    ResultSet rs;                // la variable recibe el string de los campos de sql



Ahora realizamos el codigo para el botón Guarda

    private void btnGuardaActionPerformed(java.awt.event.ActionEvent evt) {                                         
        Connection con = null; //asegura que no hay valor previo
       
        try{   //procedimiento para evaluar si se realiza la operacion
            con = getConection();
            ps = con.prepareStatement("INSERT INTO persona (Clave,Nombre,Domicilio,Telefono,Correo_electronico,Fecha_nacimiento,Genero) VALUES (?,?,?,?,?,?,?)");  // el string establece los campos a actualizar en la tabla, y ???? son los valores a recibir del formulario adicionalmente evita la inyeccion a sql
            ps.setString(1,txtClave.getText());
            ps.setString(2,txtNombre.getText());
            ps.setString(3,txtDomicilio.getText());
            ps.setString(4,txtTelefono.getText());
            ps.setString(5,txtCorreo_electronico.getText());
            ps.setDate(6,Date.valueOf(txtFecha_nacimiento.getText())); //para la fecha se usa import java.sql.Date;
            ps.setString(7,cbxGenero.getSelectedItem().toString()); // es la forma de tomar el item del combo box
           
            int rs = ps.executeUpdate(); //executeUpdate() regresa un booleano 1 si actualizo 0 no actualizo
           
            if(rs > 0){
                JOptionPane.showMessageDialog(null, "Persona agregada");
            }else{
                 JOptionPane.showMessageDialog(null, "Error Persona no agregada");
            }
           
            con.close();
           
        } catch(Exception e){
          System.err.println(e);
        }
    } 

Formemos el codigo para limpiar los campos (cajas de datos) se agrega despúes de public static Connection getConection()



 private void limpiarCajas(){
        txtClave.setText(null);
        txtNombre.setText(null);
        txtDomicilio.setText(null);
        txtTelefono.setText(null);
        txtCorreo_electronico.setText(null);
        txtFecha_nacimiento.setText(null);
        cbxGenero.setSelectedIndex(0);
       
    }

Este procedimiento puede ser incluido cuando se guardan los datos en la tabla para esperar mas datos.

 int rs = ps.executeUpdate(); //executeUpdate() regresa un booleano 1 si actualizo 0 no actualizo
           
            if(rs > 0){
                JOptionPane.showMessageDialog(null, "Persona agregada");
                limpiarCajas();
            }else{
                 JOptionPane.showMessageDialog(null, "Error Persona no agregada");
                 limpiarCajas();
            }
           
            con.close();

El proceso se puede ver aqui:

Primer parte almacenar datos