Para tutorías y/o asesorías virtuales sobre JAVA SE y/o MySQL, escríbeme al formulario de contacto.

BUSCA MÁS CONTENIDO AQUÍ:



Curso de JAVA: Cómo hacer un Pool de Conexiones?




En el anterior capítulo de nuestro Curso de JAVA, vimos cómo podíamos conectar una aplicación hecha en JAVA con una base de datos, pero de forma básica; hay que tener algo presente y es que esta forma de conectar la hemos llamado básica, ya que es utilizada para programas que no realizan conexiones concurrentes, como por ejemplo, programas que son utilizados por muy pocos usuarios; pues uno de los contra de este tipo de conexión, es que consume muchos recursos, lo cual afecta el rendimiento de nuestra aplicación y por supuesto del equipo y/o servidor.
Por esta razón, en el presente capítulo desarrollaremos y/o mostraremos una forma más avanzada, efectiva y optimizada para conectar nuestras aplicaciones con bases de datos. Esta forma es conocida como: Connection Pool o Piscina de Conexiones, ya que consiste en un agrupamiento o conjunto de conexiones abiertas, realizadas a nuestra base de datos y que pueden ser reutilizadas.

Explicación por Videotutorial:



Explicación por Foto-Tutorial: 

*Primero que todo, lógicamente debemos de contar ya con una Base de datos previamente creada (si aún no la tienes o no sabes cómo crearla, puedes ver nuestro artículo: Cómo crear una Base de datos en MySQL, con phpMyAdmin y MySQL Workbench?).

*Procederemos a:
Descargar la librería commons-dbcp-1.4.jar, la librería commons-pool-1.6.jar, y la librería mysql-connector-java-5.1.16-bin.jar. 
Las copiamos y las pegamos en la carpeta de nuestro proyecto, y las agregaremos a las librerías del mismo:

Archivos .jar en la carpeta de nuestro proyecto


*Nos ubicaremos en Netbeans IDE, y en nuestro proyecto localizamos la carpeta “Libraries” (Bibliotecas), la seleccionamos, damos clic derecho sobre la misma y escogemos la opción “Add JAR/Folder…”: 

Clic derecho en Libraries y escogemos la opción Add JAR/Folder...


*Nos saldrá una nueva ventana, lo que tenemos que hacer es buscar a través de dicha ventana, los archivos “.jar” que descargamos con anterioridad; luego de ubicarlos los seleccionamos y damos clic en el botón “Abrir”. Ahora si expandimos nuestra carpeta Libraries, observaremos que ya contamos con estos archivos en nuestro proyecto: 

 

  Seleccionamos los archivos .jar para agregarlos a las librerías de nuestro proyecto 

 Librerías agregadas al proyecto

 

 

*Ahora dentro de nuestro paquete “Metodos” (si necesitas saber cómo crear un paquete, te será de mucha ayuda leer nuestro artículo: Curso de JAVA: Cómo hacer un proyecto, un paquete y un formulario?) crearemos una Clase, la cual llamaremos “Pool”:  

 

  Creamos una nueva Clase

 Le damos un nombre a nuestra clase java
Clase Pool creada



*Procederemos a pegar el siguiente código dentro de la clase que hemos creado:

    public DataSource dataSource;

    public String db = "fundacion";
    public String url = "jdbc:mysql://localhost/"+db;
    public String user = "root";
    public String pass = "123";



    public Pool(){

        inicializaDataSource();

    }



    private void inicializaDataSource(){


        BasicDataSource basicDataSource = new BasicDataSource();

        basicDataSource.setDriverClassName("org.gjt.mm.mysql.Driver");
        basicDataSource.setUsername(user);
        basicDataSource.setPassword(pass);
        basicDataSource.setUrl(url);
        basicDataSource.setMaxActive(50);


        dataSource = basicDataSource;

    }



*Nos saldrán algunos errores en el código, lo cual se debe a que necesitamos importar ciertas librerías, para solucionar esto colocaremos fuera de la clase, más exactamente después de “package Metodos;” y antes de la línea “public class Pool {“, el siguiente código:

import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;

*Para mayor claridad y teniendo en cuenta todo lo anterior, nuestro código quedaría de la siguiente forma:

package Metodos;

import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;



public class Pool {


    public DataSource dataSource;

    public String db = "fundacion";
    public String url = "jdbc:mysql://localhost/"+db;
    public String user = "root";
    public String pass = "123";



    public Pool(){

        inicializaDataSource();

    }



    private void inicializaDataSource(){


        BasicDataSource basicDataSource = new BasicDataSource();

        basicDataSource.setDriverClassName("org.gjt.mm.mysql.Driver");
        basicDataSource.setUsername(user);
        basicDataSource.setPassword(pass);
        basicDataSource.setUrl(url);
        basicDataSource.setMaxActive(50);


        dataSource = basicDataSource;

    }



}



*En resumen, lo que hacemos en el código es crear variables que contendrán valores específicos, como la dirección del servidor, el usuario y la clave para acceder a la base de datos, y el nombre de la misma; luego se crea un método con el cual obtendremos la conexión a nuestra BD; claro está, usando los datos que almacenamos en las variables y por supuesto el driver y/o la librería que descargamos.   
Si quieres una explicación más detallada sobre cada línea del código anterior, no dudes en visitar el siguiente enlace: 
Código JAVA: Conectar JAVA con una base de datos usando un Pool de conexiones





*Ahora haremos una prueba para verificar que nos podemos conectar a nuestra base de datos, para esto nos iremos a nuestro formulario principal y daremos doble clic sobre un botón que vamos a agregar para hacer la prueba:

Agregamos un botón a nuestro formulario

Damos doble clic sobre nuestro botón para entrar al método


*Procedemos a borrar el comentario que hay en el método del botón por defecto:

Comentario por defecto en el método del botón

Eliminamos el comentario que esta en el método del botón


*Pegaremos el siguiente código dentro de dicho método: 

                                                    
        Pool metodospool = new Pool();
        java.sql.Connection cn = null;


        try {

            cn=metodospool.dataSource.getConnection();

            if(cn!=null){

                JOptionPane.showMessageDialog(null, "Conectado");

            }

        } catch (SQLException e) {

            System.out.println(e);

        }finally{


                try {

                    cn.close();

                } catch (SQLException ex) {

                    System.out.println(ex);

                }


        }



*Nos saldrán algunos errores en el código, lo cual se debe a que necesitamos importar ciertas librerías, para solucionar esto procederemos a importarlas dando clic en el bombillito que sale con error al lado de nuestro código, y luego seleccionando las librerías necesarias:

Importamos la Clase Metodos.Pool

Importamos la Clase swing.JOptionPane

Importamos la Clase sql.SQLException

Método para el test de conexión


*En el código lo que hacemos es instanciar un objeto de la clase Pool(); luego obtenemos de la variable “dataSource” (que pertenece a la clase Pool), la conexión establecida entre nuestra aplicación y la base de datos; y la almacenamos en una variable tipo Connection; ahora, verificamos a través de un condicional “if”, si la conexión es exitosa, en caso tal, se nos mostrará una ventana con el mensaje “Conectado”; luego se procede a desconectar nuestra aplicación de la base de datos. Por último sólo nos resta ejecutar nuestro formulario principal y presionar el botón que realiza el test de conexión:

Ejecutamos el formulario principal y damos clic en el botón para realizar el test de conexión

Mensaje de confirmación de conexión exitosa con nuestra Base de datos

Con esto ya podremos llevar a cabo el desarrollo de aplicaciones más avanzadas, que necesitan conectarse con bases de datos de forma concurrente y así gestionar datos; es decir, guardarlos, modificarlos, etc., pero de una forma más óptima y eficaz.

Si deseas descargar el video, junto con el fascículo del presente tema del curso de JAVA, sólo debes dirigirte a nuestra Zona de Descargas, y dar clic sobre el icono "Curso de JAVA Parte 13".

Si deseas ver la Parte 12 del Curso de JAVA, puedes dar clic en el siguiente enlace: Curso de JAVA: Cómo conectar JAVA con una Base de datos? (Forma básica)
Para tener acceso a todos los temas desarrollados hasta ahora en el presente curso, puedes ver todos los capítulos de Cómo lo hago en JAVA?

Si te fue de gran ayuda este material, no olvides compartirlo con tus amigos. 
Si tienes dudas o sugerencias al respecto; puedes dejarnos tus comentarios.
Bendiciones...




Comparte este artículo






Sobre El Autor

Eduardo Bastidas UH

Cristiano y Colombiano. Analista de Sistemas & Blogger.
Me motiva mucho el poder compartir día tras día lo que he aprendido y voy aprendiendo en el área de las Tecnologías de la Información y las Comunicaciones.

29 comentarios:

  1. PARA TENER EN CUENTA:
    La línea de código que usamos en el método inicializaDataSource(), de la Clase Pool():
    basicDataSource.setDriverClassName("org.gjt.mm.mysql.Driver");
    Actualmente no es necesaria, así que la puedes obviar (eliminarla), ya que el driver se cargará automáticamente; sin embargo, si la dejas o la quitas, el código seguirá funcionando.

    ResponderEliminar
    Respuestas
    1. hola amigo. muchas gracias
      disculpe me sale un error en la clase Pool

      Eliminar
  2. " cn=metodospool.dataSource.getConnection(); "

    Hola Amigo, mira tengo un problema es esta linea, aparece esto:

    Cannot find smbol

    ResponderEliminar
    Respuestas
    1. Saludos estimado Crixttian, en las penúltimas imágenes de este artículo te podrás dar cuenta que ese error "cannot find symbol", surge por falta de implementación de las librerías necesarias para el funcionamiento del código; por lo cual, allí te explico la forma de importarlas. Ahora, debes de tener presente importar exactamente las que se te indican, o sino te seguirá apareciendo dicho error.

      ¡Cristo Te Ama! :)
      Bendiciones...

      Eliminar
  3. Buenos días Eduardo.
    Si las importe todo el pie de la letra, me aparece tal cual, pero es esa linea me sigue apareciendo el dicho error. o veo que cundo tu estas escribiendo "getConnection();" java te muestra opciones y ahí aparece Connection, pero a mi no!!
    Y esa el la parte que no reconoce porque la sombrea y a bajo de cannot find symbol, dice que la localización de getConection es: Metodos.

    Espero haber sido claro, yo sé que usted esta dando un buen tutorial.
    Muchas gracias Dios te bendiga.

    ResponderEliminar
    Respuestas
    1. Si lo deseas puedes enviarme tu proyecto al correo: desarrollouh@hotmail.com, para revisar bien cuál es el inconveniente que tienes.

      Eliminar
    2. hola crixxtian, en el tutorial que esta excelente me ayudo mucho, pero falto poner la libreria import java.sql.connection;
      quizas alla este tu error que dice "no se encontro el objeto" (o simbolo)
      agregalo...

      Eliminar
  4. Buenas tardes, gracias por la información, ya estoy tratando de usarlo en mi proyecto pero la sentencia dataSource.getConnection(); se tarda en conectarse por Internet a mi servidor entre 5 y 20 segundos. Tendrás algún consejo o una idea que pueda trabajar a ver si es más rápido. Saludos.

    ResponderEliminar
    Respuestas
    1. Saludos estimado Ramón González.
      Si has desarrollado una aplicación Java de escritorio, y tienes tu base de datos alojada en un servidor remoto en internet, te recomiendo que apliques y hagas uso de los Java Web Services, ya que es lo más recomendable en este tipo de casos.
      Actualmente no tengo un tutorial sobre este tema, pero en YouTube encontrarás una serie de videos al respecto, los cuales te serán de gran ayuda.

      ¡CRISTO TE AMA!

      Bendiciones...

      Eliminar
  5. amigo muchas gracias, muy bueno el Blog.
    Ahora, quisiera me ayudaras en algo, tengo implementado el pool de conexiones, sin embargo luego de un tiempo de inactividad la conex con la db Mysql se pierde, en el catch aparece:

    com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    The last packet successfully received from the server was 327.594 milliseconds ago. The last packet sent successfully to the server was 1 milliseconds ago.

    ResponderEliminar
    Respuestas
    1. Saludo estimado amigo, con respecto a tu inconveniente con el pool de conexiones, debes realizar varias verificaciones, entre ellas:

      1- Asegúrate de que estés implementando la línea de código que te permite liberar la conexión usada actualmente (ej. "cn.close();").

      2- Verifica que el servicio de tu servidor de base de datos esté activo.

      3- En caso de que estés accediendo a una base de datos remota, es posible que haya interrupciones y/o caídas en la red.

      Cualquier inquietud déjame tu comentario.
      Si llegas a solucionar tu inconveniente con la conexión a tu base de datos, regálanos dicha solución para cualquiera de nuestros visitantes que tengan el mismo problema.

      Bendiciones...

      Eliminar
  6. Eduardo muchas gracias por tu tiempo, ahora te explicaré con mas detalle:
    1) es un sistema de facturación hecho en java swing con ide Netbeans
    2) la conexión a BD es a través de Mysql
    3) cada hilo de conexión siempre lo cierro (en un tryCatch finally: cn.close)
    ahora, el error:

    supongamos que busco un producto en la BD, el sistema lo busca y lo trae... ahí cierro la conexión
    pero, si pasan 4.5min e intenta conectarse de nuevo, me sale el error que te comentaba
    (The last packet successfully received from the server was 327.594 milliseconds ago. The last packet sent successfully to the server was 1 milliseconds ago.
    )
    ...por lo que toca cerrar y volver a abrir el JFrame, y el error vuelve y aparece cada que intente conectarme
    luego de 4.5minutos.

    Gracias por la ayuda.

    ResponderEliminar
    Respuestas
    1. Saludos estimado amigo, viendo y estudiando tu explicación, este comportamiento se debe a un detalle en los archivos de configuración del servidor MySQL.

      1- Ejecuta el "Bloc de Notas (Notepad)" como Administrador. Procede a dar clic en el menú "Archivo"; luego, escoges la opción "Abrir". Debes dirigirte a la carpeta de instalación de MySQL y encontrarás varios archivos cuya extensión es ".ini".

      2- Procede a abrir el archivo "my.ini", una vez abierto procede a dar clic en el menú "Edición" y escoges la opción "Buscar", procederás a buscar las variables: interactive_timeout y wait_timeout y sólo te importará el resultado que no esté precedido por el símbolo "#" (numeral).

      3- Una vez lo encuentres, cambiarás el valor que tengan (y me comentas que valor tenían), por el valor "28800".
      Si no llegas a encontrar dichas variables, entonces procede a añadirlas al final del archivo, de la siguiente manera:
      wait_timeout=28800
      interactive_timeout=28800

      4- Guardas los cambios.

      5- Reinicia MySQL Server.

      Trata de ejecutar tu proyecto nuevamente y verifica que funcione de forma efectiva.

      Cualquier inquietud me comentas.

      Bendiciones...

      Eliminar
  7. SI PUEDO CAMBIAR A POSTGREL EN VEZ DE MYSQL. QUIERO SABER SI ES LO MISMO Y NO PASA NADA

    ResponderEliminar
    Respuestas
    1. Saludos estimad@ visitante, para realizar tu conexión con una base de datos en PostgreSQL, deberás realizar algunos ajustes:

      1- La variable "public String url" quedaría así: "jdbc:postgresql://localhost/"+db;

      2- Sigue la recomendación que doy en el primer comentario de este artículo, el cual consiste en eliminar la línea de código:
      basicDataSource.setDriverClassName("org.gjt.mm.mysql.Driver");

      Haz esos cambios y realiza las pruebas y me comentas.

      Bendiciones...

      Eliminar
  8. hola mi estimado super buenos sus tutoriales pero me da error en la linea
    import org.apache.commons.dbcp.BasicDataSource;
    dice q en el package no existe me podrias ayudar porfavor
    saludos y bendiciones :)

    ResponderEliminar
    Respuestas
    1. Saludos estimado visitante.
      Debes cerciorarte de que hayas importado las librerías que se te indican en los primeros pasos.
      Sin embargo, te recomiendo que mires la explicación de cada fragmento de código; la cual puedes encontrar dando CLIC AQUÍ.

      Cualquier duda déjanos tu comentario.

      Bendiciones...

      Eliminar
  9. Buenas noches.
    Muchas gracias por el material. He descargado e importado las librerías como se indica, pero me sigue saliendo en la siguiente línea: BasicDataSource basicDataSource = new BasicDataSource();
    De antemano muchas gracias por la respuesta.

    ResponderEliminar
    Respuestas
    1. Saludo Cordial estimado Angel B.

      Debes de cargar todas las librerías .jar y no las que están comprimidas en .zip; es decir, debes proceder a descomprimir las librerías antes de importarlas a tu proyecto.

      Tus librerías no deben estar así, ej.:
      commons-dcp-1.4.jar.zip

      Deben quedar así, ej.:
      commons-dcp-1.4.jar

      En caso de que tengas tus librerías bien importadas, en la línea en la que te sale el error, en la parte donde está el número de la línea de código aparece un icono en forma de bombillo, pon el cursor del mouse encima del mismo y/o dale clic, y verifica el mensaje de error que te está saliendo y regálamelo por favor.

      Bendiciones...

      Eliminar
  10. Hola, ya he intentado con anterioridad esto pero me queda duda según tu vídeo entonces ¿cada que se hace una conexión se debe instanciar de nuevo el objeto de la clase donde este la conexión? tengo la versión pool2-2.4.2 y dbcp2-2.1.1.
    Realiza la primera conexión cuando corro el programa y de allí heredo la conexión a otra clase realiza la primer consulta y cierro la conexión en el finally pero cuando intento hacer otra conexión me da error "java.sql.SQLException: Operation not allowed after ResultSet closed" sabrás que lo esté causando. agradezco tu ayuda.

    ResponderEliminar
  11. Buenas tardes Eduardo, gracias por el tutorial me esta ayudando mucho a comprender el mundo java, tengo una pregunta con la clase Pool.

    ya revise varias veces el código y esta bien pero me genera un error en una importación de librería.
    //import org.apache.commons.dbcp.BasicDataSource;// me indica que el paquete no existe.

    me podrías ayudar para solucionar el problema.

    Agradezco tu tiempo.

    Cordialmente,

    Juan Manuel L.

    ResponderEliminar
    Respuestas
    1. Saludos estimado Juan Manuel, es posible que tengas el mismo inconveniente que se le ha presentado a algunos amigos que me han escrito; por lo cual, te doy las mismas recomendaciones, que son:

      Debes de cargar todas las librerías .jar y no las que están comprimidas en .zip; es decir, debes proceder a descomprimir las librerías antes de importarlas a tu proyecto.

      Tus librerías no deben estar así, ej.:
      commons-dcp-1.4.jar.zip

      Deben quedar así, ej.:
      commons-dcp-1.4.jar

      En caso de que tengas tus librerías bien importadas, en la línea en la que te sale el error, en la parte donde está el número de la línea de código aparece un icono en forma de bombillo, pon el cursor del mouse encima del mismo y/o dale clic, y verifica el mensaje de error que te está saliendo y regálamelo por favor.

      Bendiciones...

      Eliminar
  12. Buenas amigo, EH visto el tutorial me parece genial, lo estoy queriendo probar con postgresql ya que actualmente tengo problemas con la conexión actual. Lo que me gustaría saber es si es bueno para el ámbito de producción este tipo de conexion desde ya gracias y saludos.

    ResponderEliminar
    Respuestas
    1. Saludos estimado Richard Portillo, gracias por dejarnos tus comentarios.
      El Pool de conexiones es muy útil en un ambiente de producción ya que te permitirá establecer y mantener una serie de conexiones disponibles para ser usadas por procesos que ejecute tu proyecto (Software). Hay que tener en cuenta que debes configurarlo de la mejor forma para que trabaje de manera óptima.
      El Pool de conexiones es con toda seguridad para el ámbito de producción, mucho mejor en gran medida, que una Conexión Básica y/o Normal.

      Si tienes más inquietudes, no dudes en escribirnos...

      ¡CRISTO TE AMA! :)
      ¡ÉL QUIERE SER TU AMIGO!

      Bendiciones para ti y tu familia...

      Eliminar
  13. Entiendo, eh probado el codigo y me funciona muy bien, la duda que aun tengo amigo es como puedo configurar para que solo me mantenga una sola conexion, ya lo probe con algunos formularios y cada vez que que las abro vuelve a abrir una nueva conexion. Ya que en el init de mi from ( Pool metodospool = new Pool(); java.sql.Connection cn = null; cn=metodospool.dataSource.getConnection();) vuelvo a hacer estos codigos. No entiendo muy bien si debo de volver a cerrar la conexion al cerrar cada ventana o como. Desde ya gracias amigo. Dios te bendiga.

    ResponderEliminar
    Respuestas
    1. Saludos estimado Richard Portillo, cada vez que realices una conexión y luego de ejecutada la consulta a tu Base de Datos, debes proceder a liberar dicha conexión, lo cual puedes hacer aplicando el método ".close();" al objeto de tipo Connection (donde obtienes y administras tu conexión), y asignarle posteriormente un valor "null" a dicho objeto, ej.:

      cn.close();
      cn=null;

      En tu clase Pool, puedes usar el objeto de tipo BasicDataSource, y aplicarle el método ".setMaxActive();" para definir el máximo de conexiones activas, y también puedes implementar el método ".setMaxIdle()" para establecer el máximo de conexiones que estarán disponibles en el Pool para ser usadas posteriormente, ej.:

      basicDataSource.setMaxActive(50);
      basicDataSource.setMaxIdle(30);

      Bendiciones...

      Eliminar
  14. Entiendo, hize asi pero aun asi me abre varias conexiones lo verifico con el comando "show PROCESSLIST;" la diferencia es que ahora derepente me muestra es hay 70 conexiones abiertas luego varia y baja solo a 15. No se si eso seria bueno o malo. En mi caso tengo una clase Pool que seria mi conexion luego esa clase instacio en los diferentes abm (formularios) a abrir un formulario me muestra una consulta al filtrar cada vez que se presiona vuelve a abrir otra nueva conexion. Creandome un problema que llego al maximo de clientes conectados al servidor. La verdad que primero prove la conexion normal y ocurria mucho con el pool solo algunas veces.

    ResponderEliminar
    Respuestas
    1. Saludos estimado Richard Portillo, puedes emplear algunas o todas las siguientes sugerencias:

      Configura tu DBMS (Administrador de Base de Datos):
      1- Aumenta el número de conexiones simultáneas que permite tu servidor de Base de Datos, esto lo haces modificando la variable "max_connections=100".
      2- Disminuye el tiempo de espera que tarda MySQL para cerrar una conexión, esto lo haces modificando la variable "wait_timeout=1".

      Configura tu Pool de Conexiones:
      1- Establece en la variable ".setMaxActive()" un valor menor al número de conexiones simultáneas que permite tu Servidor de Base de Datos.
      2- Establece en la variable ".setMaxIdle()" un valor menor al que le asignaste al método ".setMaxActive()".

      NOTA: Cada vez que instancias tu Clase Pool, se creará una nueva conexión.

      Bendiciones...

      Eliminar
  15. La verdad que no consigo solucionar el problema amigo, mi gestor de base de datos es Postgresql.
    en un momento me da un sensaje de que hay muchos clientes conectados. Y si intento cerrar la conexion despues de un select, insert, etc. Me da el error de conexion cerrada. De todo modo muchas gracias.

    ResponderEliminar


RECIBIR NOTICIAS POR EMAIL


Suscríbete al boletín para recibir lo último en tu correo electrónico

¿NECESITAS AYUDA PARA PROGRAMAR EN JAVA SE Y MYSQL?