POOL Connection

Hola me llamo Eduardo Acevedo Reyes soy de la Ciudad de México y ya tengo 1 año en este grupo llamado JavaMéxico y este sera mi primer post. No tuve tiempo antes pero al por fin e terminando mi Licenciatura en Informática en la Universidad Insurgentes en lo que he tomado como profesión y pasión la programación y me eh decidido a subir este tipo de material que sera de ayuda para algunos y de critica para otros. Aquí el punto fundamental del por que subo este post y los que suba posteriormente, es el echo de que personas como @ezamudio , OscarRyz , @luxspes , @Sr. Negativo y muchos más fueron parte fundamental de mi formación académica y sería de mucho interés saber su opinión acerca de lo que he aprendido en mi Universidad y con Ustedes (JavaMéxico, miembros). Gracias

Bueno aquí dejare el código que uso siempre para conectarme a mi base de datos (PostgreSQL, *mi favorita*).
Espero este bien formulado mi contenido ya que este tipo de conexión la uso no importando la magnitud he impacto en los procesos y usuarios que la requieran solo que ya me acostumbre a manejar la así.

Comento igual que esta conexión la tengo dentro de un proyecto semi-profecional que use en mi servicio social el cual esta en la arquitectura
MVC ...

package sat.sistemaconsultasaggc.modelo;
import sat.sistemaconsultasaggc.controlador.siscoBean;

import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;

import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.sql.*;
import javax.naming.*;

public class model   {

        private static Connection conn;
       
        public static void conectado()throws SQLException, ServletException {
                if(estoyConectado()) throw new SQLException("Ya esta¡ Conectado");
                try{
                       Context cxt= new InitialContext();
                       DataSource ds= (DataSource) cxt.lookup("java:comp/env/jdbc/sisco");
                         
                         if(cxt == null) throw new Exception("ERROR -no se logro crear el contexto del DataSource");
                         if(ds == null) throw new Exception ("ERROR -no se concreto  el origen de datos");
                         
                         if(ds != null) conn=ds.getConnection();
                         
                }catch(Exception ex){
                        throw new ServletException ("No se pudo concretar la acción en ",ex);
                }
        }
       
        public static boolean estoyConectado(){
                return (conn != null);
        }
        public static void desconectar(){
                if(conn != null){
                        try{
                                conn.close();
                        }catch(Exception ex){
                                ex.printStackTrace();
                        }finally{
                                conn= null;
                        }
                }
        }
}

Y aquí su uso en un método que tengo como ejemplo

public static LinkedList<siscoBean> getNomRazon(String nomRazon)throws SQLException, ServletException{         
                if(!estoyConectado()){
                        conectado();
                }
                LinkedList<siscoBean> listaNomRazon= new LinkedList<siscoBean>();
                PreparedStatement pstmt=null;
                ResultSet rs=null;
               
                try{
                       
                  pstmt=conn.prepareStatement("SELECT DISTINCT  nom_razon, rfc from Vista_Registros where nom_razon like ? ");  
                  pstmt.setString(1,nomRazon.trim().toUpperCase() + "%");                                
                  rs=pstmt.executeQuery();
                       
                        while (rs.next()) {
                               
                                siscoBean sB = new siscoBean();
                               
                                sB.setNom_razon(rs.getString(1));
                                sB.setRfc(rs.getString(2));
                               
                                listaNomRazon.add(sB); 
                               
                        }
                }finally{
                        if(pstmt != null){
                                pstmt.close();
                        }
                        if(rs != null){
                                rs.close();
                        }
                }
                desconectar();
               
                return listaNomRazon;
        }

Dentro Proyecto echo en Eclipse Mars mi distribución de carpetas el archivo context.xml se encuentra en META-INF
con el siguiente contenido

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/Sisco">
    <Resource name="jdbc/sisco" auth="Container" type="javax.sql.DataSource"
    maxActive="100" maxIdle="30" maxWait="100000"
    username="postgres" password="toor" driverClassName="org.postgresql.Driver"
    url="jdbc:postgresql://localhost:5432/sisco" />
</Context>

Donde
  • path="/Sisco" --> Es el nombre de mi dynamic web project
  • username="postgres" --> Es el nombre del usuario de mi base de datos (esto puede cambiar dependiendo de la configuración que tengas)
  • url="jdbc:postgresql://localhost:5432/sisco" / --> es la ruta de conexión hacia mi base de datos llamada sisco
  • Que opinan ?

    Como Nota. Les comento que mi JAR del Driver de PostgreSQL lo tengo en mi carpeta lib del apache-tomcat-7.0.55

    Les mando un gran saludo.

    Comentarios

    Opciones de visualización de comentarios

    Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
    Imagen de ezamudio

    Hola

    Antes que nada, me da gusto saber que hemos ayudado en tu formación.

    Pero creo que no hicimos un muy buen trabajo... ese código me parece que está innecesariamente enredado. Si querías hacer algo reusable, era mejor hacerlo de otra forma; tal vez algo similar al JdbcTemplate de Spring.

    Supongo que este código que muestras en la primera parte, lo copias y pegas a todas tus clases que necesitan usar una conexión de base de datos. Esa no es la manera de reutilizar código; es mejor tener un componente que obtenga una conexión, se la pueda pasar a otro, y al final siempre la cierre, pase lo que pase. En tu ejemplo, el desconectar() debería estar también dentro del bloque finally, o no se ejecutará si ocurre una excepción (y bien podría ser un simple conn.close()). Si ya estás usando Java 7, puedes usar el try-with-resources para ahorrarte un poco de código.

    Está bien la definición del datasource, aunque yo usaría una de pool (como la de commons DBCP) para reutilizar conexiones (eso no está sucediendo en tu ejemplo).

    Si no puedes meter dependencias a tu proyecto para usar algo como JdbcTemplate, entonces puedes hacer uno tú, aunque sea un poco más rudimentario, tal vez algo así:

    interface Accion {
      public void accion(Connection conn);
    }

    class DB {
      private final DataSource ds;
      public DB(String jndiPath) throws WhateverException {
        ds=(DataSource)cxt.lookup(jndiPath);
      }

      public void do(Accion accion) {
        try (Connection c = ds.getConnection()) {
          accion.accion(c);
        } finally {
        }
      }
    }

    Y entonces la puedes usar en otros componentes:

    class Ejemplo {
      private final DB db;
      public Ejemplo() throws BlaException {
        db = new DB("java:comp/env/bla");
      }
      public List<Dato> throws SQLException, BlaException {
        db.do(new Accion() {
          public void accion(Connection conn) {
            try (PreparedStatement ps = conn.prepareStatement("SELECT bla")) {
              ps.setString(1, "ble");
              try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                  //bla
                }
              }
            } finally {
            }
          }
        });
      }
    }

    Te dejo de tarea cómo sacar la lista de la clase anónima interna hacia la clase externa...

    Imagen de hellocannibal

    Hola, Muchas Gracias

    Hey, la persona que esperaba que respondiera a mi blog me siento muy contento por la retroalimentación que he recibido hoy por parte de usted Sr.Ezamudio y por los próximos y posibles miembros de esta gran comunidad. He de comentar y creo que desde el principio lo debí de mencionar mi poca experiencia en la programación y espero no estar haciendo mal en subir mi código en esta comunidad yo lo hago con la mejor intención que tengo ya que como mencione esta comunidad fue de gran ayuda en la formación que recibí en la universidad ha pesar de ser una carrera más enfocada a lo administrativo me mantuve en meta en mis dos materias que tuve de programación POO Y POO2 Y es por eso que tal vez exista alguna persona como yo que requiera de una mínima linea de código para ampliar sus horizontes de solución. Tal vez no es la mejor solución lo sé pero para eso subí el post para que personas que saben más que yo y tienen el tiempo y el don de expresar lo que saben.

    Tomare en cuenta lo aquí mencionado.

    Imagen de hellocannibal

    Tarea

    Mi duda.
    No le falta ser estático y ponerle un nombre ah ese método para pesarle el parámetro 'ble' o algo relevante puede ser que mi falta de conocimientos no sepa la respuesta a esto.(jajaja)

     public List<Dato> throws SQLException, BlaException

    Como por ejemplo:

     
    class ejemplo{
    public static List<Datos> geDatosRequeridos(pasar algún parametro)throws SQLException,ServletException{ }}

    Pues según yo para sacar el contenido o valla pues para llamar a un método que esta dentro de una clase y llamarlo en otra o a un servlet lo que hago es
    crear otra lista y pesarle ya lo ahí contenido.

    List<datosOtros> lista = null;
    try{
    lista=ejemplo.geDatosRequeridos();
    }finally{}
    ??? ???

    -----
    Eh aquí algo que igual como lo mencionas es más simple y menos complicado de lo que hago :) DAO con Spring

    Imagen de ezamudio

    convenciones

    Aunque no es obligatorio en Java, es muy recomendable seguir las convenciones: nombres de clase con mayúscula, constantes todas mayúsculas, todas las demás declaraciones con minúscula.

    Vi que usas bastantes static en tu código. Eso impide que se puedan tener varias instancias de la misma clase, cada una con su propio estado, entre otras desventajas.

    Y ahora que veo mi código, algo hice raro porque el método no tiene nombre... debe ser más bien algo así:

    public class Ejemplo {
      public List<Dato> getDatos(final String nombre) throws SQLException, BlaException {
        final List<Dato> datos = new ArrayList<>();
        db.do(new Accion() {
          public void accion(Connection conn) {
            try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM bla WHERE nombre= ?")) {
              ps.setString(1, nombre);
              try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                  Dato row = ...
                  datos.add(row);
                }
              }
            } finally {
            }
          }
        });
        return datos;
      }
    }
    Imagen de Sr. Negativo

    Jeje

    ...el echo de que personas como @ezamudio , OscarRyz , @luxspes , @Sr. Negativo y muchos más fueron parte fundamental de mi formación académico...

    jeje no lo pude evitar (yo al borde de las lágrimas).

    Que bien que pudimos contribuir en algo. Suerte. :D

    Imagen de hellocannibal

    Jajaja

    Se escucho y lo escribir un poco tipo guión de telenovela jajaja lo sé !!!

    ¡Qué gran privilegio! :-P

    ¡Qué gran privilegio! :-P