sábado, 10 de abril de 2010

Implementando un Singleton Manager de Conexión

En aplicaciones cliente/servidor se acostumbra a tener una conexión a BD única por usuario, para poder hacerlo vamos a implementar un manager de conexión.

1.- Este es el código del manager:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Carlos Rojas
*/
public class ConnectionManager {

private static String driver = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost:3306/Prueba";
private static String user = "prueba";
private static String password = "prueba";
private static Connection con;

/**
* Inicializa una nueva conexión con parámetros nuevos
* @param driver
* @param url
* @param user
* @param password
*/
private ConnectionManager(String driver, String url, String user, String password) {
ConnectionManager.driver = driver;
ConnectionManager.url = url;
ConnectionManager.user = user;
ConnectionManager.password = password;
}

/**
* Retorna una conexión por defecto
* @return
*/
public static Connection getConnection() {
if (con == null) {
try {
Class.forName(driver);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
try {
con = DriverManager.getConnection(url, user, password);
} catch (SQLException ex) {
Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Se genero una nueva instancia de Connection");
}
System.out.println("Se retorno una instancia de Connection");
return con;
}

/**
* Retorna una conexión unica a partir de los parametros de conexion, en caso que la instancia de la conexión
* no sera nula, retornara la instancia
* @param driver
* @param url
* @param user
* @param password
* @return
*/
public static Connection getConnection(String driver, String url, String user, String password) {
if (con == null) {
new ConnectionManager(driver, url, user, password);
try {
Class.forName(ConnectionManager.driver);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
try {
con = DriverManager.getConnection(ConnectionManager.url, ConnectionManager.user, ConnectionManager.password);
} catch (SQLException ex) {
Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
return con;
}

public static void closeConnection() {
if (con != null) {
try {
con.close();
} catch (SQLException ex) {
Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

2.- Ahora vamos a utilizar la clase TestConnectionManager de prueba para usar el manager:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
*
* @author Carlos Rojas
*/
public class TestConnectionManager {
public TestConnectionManager(int x){
Connection con = ConnectionManager.getConnection();
try {
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select "+x);
while(rs.next()){
System.out.println(rs.getObject(1));
}
} catch (SQLException ex) {
Logger.getLogger(TestConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}

public static void main(String[] args) {
new TestConnectionManager(1);
new TestConnectionManager(2);
new TestConnectionManager(3);
new TestConnectionManager(4);
}
}

3.- La salida del programa será la siguiente:

Se genero una nueva instancia de Connection
Se retorno una instancia de Connection
1
Se retorno una instancia de Connection
2
Se retorno una instancia de Connection
3
Se retorno una instancia de Connection
4

4. La primera vez que se ejecuta el método getConnection() la instancia de la variable "con" es nula, por lo tanto se inicializa el singleton. Las llamadas posteriores solo devuelve la instancia ya previamente creado.