Un pool de conexiones de manera simple es un conjunto limitado de conexiones hacia una base de datos.

Cuando se trata de trabajar con bases de datos, generalmente lo que se hace es obtener una conexión, realizar las operaciones SQL que se requieran y para finalizar cerrar la conexión. El problema reside en el coste de recursos para el procesador que supone el estar abriendo y cerrando conexiones.

Un pool de conexiones lo que hace es mantener abiertas un numero determinado de conexiones físicas que se irán reutilizando automáticamente para aumentar la eficiencia.

A continuación veremos como se escribe una clase que generara un pool de conexiones y que podremos utilizar en nuestras aplicaciones de manera sencilla. Para comenzar necesitaremos de 3 librerías que podemos encontrar en una búsqueda rápida en google.

  • ommons-pool2-2.6.0.jar
  • commons-dbcp2-2.5.0.jar
  • commons-logging-1.2.jar

y una cuarta que dependerá del motor de base de datos al que se requiera conectar  nuestro aplicativo, en este caso solo con fines de demostración utilizare MySql.

  • mysql-connector-java-8.0.13.jar

Una vez agregadas estas librerías a nuestro proyecto podemos comenzar a escribir la clase Pool.java la cual principalmente contara con los siguientes atributos. No se olviden de agregar los import necesarios.

    private DataSource dataSource;
    private String driver,
            user,
            password,
            url;
    private int minConnections, maxConnections;
    private Connection connection;
    public Statement command;

También deberá contener un constructor que reciba los paramentos de inicialización necesarios para poder abrir las conexiones y quedaría de la siguiente forma.

    public Pool(String driver, String user, String password, String url, int minConnections, int maxConnections) {
        this.driver = driver;
        this.user = user;
        this.password = password;
        this.url = url;
        this.minConnections = minConnections;
        this.maxConnections = maxConnections;
        initializePool(this.driver, this.user, this.password, this.url, this.minConnections, this.maxConnections);
    }

Si notaron, al final del constructor esta el método initializePool() el cual es el que como su nombre lo dice sirve para incializar el pool de conexiones y dentro de este se utiliza un objeto BasicDataSource el cual se configura con el driver correspondiente al motor de base de datos en este caso de MySql, usuario, password, URL de la base de datos y el numero mínimo y máximo de conexiones que se van a mantener abiertas, posteriormente este objeto sera asignado al DataSource declarado al inicio de la clase. El método quedaría de la siguiente manera.

 private void initializePool(String driver, String user, String password, String url, int minConnections, int maxConnections) {
        BasicDataSource basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName(driver);
        basicDataSource.setUsername(user);
        basicDataSource.setPassword(password);
        basicDataSource.setUrl(url);
        basicDataSource.setMinIdle(minConnections);
        basicDataSource.setMaxTotal(maxConnections);
        dataSource = basicDataSource;
    }

Ahora solo queda crear los métodos mas importantes, los cuales se encargaran de administrar las conexiones a la base de datos. El primero de ellos sera para obtener una conexión y dejar listo el statement para realizar la consulta o modificación sobre la base de datos, el método se llamara Connect();

    public void Connect() {
        try {
            connection = dataSource.getConnection();
            command = connection.createStatement();
        } catch (Exception e) {
            System.err.println("conexion fallida: \n" + e);
        }
    }

Para finalizar necesitamos el metodo Disconnect(); el cual se va a encargar de liberar la conexión para que quede disponible para ser usada en otro momento.

public void Disconnect() {
        try {
            command.close();
            connection.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

Con esto esta terminada la clase pool y ahora podemos pasar a implementarla, aquí dejo un ejemplo de como hacer una consulta sencilla para probar el correcto funcionamiento del pool. No se olviden de sustituir los valores correspondientes a su base de datos para la conexión.

public class Main {

    public static void main(String[] args) {
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://127.0.0.1:3306/test"
        String user = "root";
        String password = "";
        int minConnections = 1;
        int maxConnections = 10;

        Pool pool = new Pool(driver, user, password, url, minConnections, maxConnections);

        for (int x = 0; x < 15; x++) {
            pool.Connect();
            try {
                ResultSet rs = pool.command.executeQuery("Select * From tbltest");
                while (rs.next()) {
                    System.out.println(rs.getString(1) + " || " + rs.getString(2));
                }
            } catch (SQLException ex) {
                System.err.println("Error    ::    " + ex);
            }finally{
                  pool.Disconnect();
            }
          
        }
    }
}

Con el código anterior se hará la misma consulta 15 veces, no debemos olvidar poner el método Disconnect(); después de terminar de usar la conexión por que de no ser así la aplicación tronara al no tener conexiones disponibles para ser utilizadas. Puedes probar esto comentando la linea pool.Disconnect(); y con esto solo podrá hacer 10 consultas (Numero máximo de conexiones configurado) ya que no se liberan las conexiones que se obtienen para hacer cada consulta.

Para terminar dejo la clase Pool.java en Gitlab para que puedas descargarla o copiarla  y agregarla a tu proyecto.