No es un bug, es una característica no documentada

lunes, 4 de julio de 2016

Java y MySQL. Patrón Singleton

21:35 Posted by Inazio Claver , 7 comments
¿Necesitas una conexión en tu aplicación Java? ¿Harto de abrir varias instancias cada vez que quieres conectarte a MySQL? ¿Estás leyendo esto con voz de anuncio?
Entonces el patrón Singleton es tu nuevo mejor amigo.

El patrón Singleton, o patrón de instancia única, es un patrón de diseño encargado de restringir la creación de objetos de una clase (o el valor de un tipo) a un único objeto. Genera una única instancia en la ejecución del programa y proporciona un acceso global a la misma.

Sirve para multitud de funcionalidades, pero en este caso vamos a ver su aplicación a la hora de conectarnos a una base de datos MySQL.



¿Cómo funciona?

Crearemos una nueva clase, por ejemplo EjemploSingleton, que será la responsable de crear la única instancia.

import java.sql.*;

public class EjemploSingleton {

}

Lo siguiente será crear una variable estática que almacenará nuestra conexión y la inicializaremos a null

private static Connection conn = null;

Después de eso deberemos crear un constructor para nuestra nueva clase, pero ojo, lo crearemos privado.
¡¿Un constructor privado?! Sí, como lo oyes. Es la forma de garantizar que solo tendremos una única instancia para la conexión.

private EjemploSingleton(){
 
    String url = "jdbc:mysql://localhost:3306/test";
    String driver = "com.mysql.jdbc.Driver";
    String usuario = "usuario";
    String password = "password";
 
    try{
 Class.forName(driver);
 conn = DriverManager.getConnection(url, usuario, password);
    }
    catch(ClassNotFoundException | SQLException e){
 e.printStackTrace();
    }
}

Vale, pero si es privado, ¿cómo vamos a crearlo? He ahí la gracia, al constructor lo llama la propia clase, a través de un método. Es lo que veremos a continuación.

Vamos a crear un método llamado getConnection en el que indicaremos que si nuestra propiedad conn es nula, vuelva a levantar el driver y crear una conexión llamando al constructor privado.
Y retornaremos la conexión para trabajar con ella.

public static Connection getConnection(){
 
    if (conn == null){
 new EjemploSingleton();
    }
 
    return conn;
}

Y una vez programada nuestra clase, podremos echar mano de esa conexión desde cualquier parte de nuestro programa llamándolo de esta forma

Connection conn = EjemploSingleton.getConnection();

Et voilá! Ya tenemos un patrón de instancia única en Java con MySQL.

El código completo es el siguiente:

import java.sql.*;

public class EjemploSingleton {

    // Propiedades
    private static Connection conn = null;
    private String driver;
    private String url;
    private String usuario;
    private String password;
 
    // Constructor
    private EjemploSingleton(){
 
 String url = "jdbc:mysql://localhost:3306/test";
 String driver = "com.mysql.jdbc.Driver";
 String usuario = "usuario";
 String password = "password";
  
 try{
     Class.forName(driver);
     conn = DriverManager.getConnection(url, usuario, password);
 }
 catch(ClassNotFoundException | SQLException e){
     e.printStackTrace();
 }
    } // Fin constructor
 
    // Métodos
    public static Connection getConnection(){
  
 if (conn == null){
     new EjemploSingleton();
 }
  
 return conn;
    } // Fin getConnection
}

7 comentarios:

  1. Hola excelente explicación pero me queda una duda en donde cierras la conexión?

    ResponderEliminar
    Respuestas
    1. Hola, gracias por comentar.
      En este ejemplo no la cierro, pero si quisieras hacerlo puedes implementar un método público estático en esta misma clase, por ejemplo:

      public static cerrarConexion()
      {
      if (conn != null)
      {
      conn.close();
      }
      }

      Eliminar
    2. Muchas gracias por la aclaración
      excelente post

      Eliminar
    3. Buenas Omar. No, este código no usa bundles

      Eliminar
  2. perdon no se si ese codigo usa bundles
    soy nnovato solo me gusta leer mas de la cuenta jeje

    ResponderEliminar
  3. Gracias y si, jajajajjaj, lo leí con voz de anunciador XD

    ResponderEliminar
  4. parce me hiciste el dia con eso de leer con voz de anuncio jajajjaja

    ResponderEliminar