2009-09-22 27 views
25

Siguiendo es mi clase de ayuda para conseguir la conexión DB:La agrupación de conexiones JDBC utilizando C3P0

He usado la agrupación de conexiones C3P0 como se describe here.

public class DBConnection { 

    private static DataSource dataSource; 
    private static final String DRIVER_NAME; 
    private static final String URL; 
    private static final String UNAME; 
    private static final String PWD; 

    static { 

     final ResourceBundle config = ResourceBundle 
       .getBundle("props.database"); 
     DRIVER_NAME = config.getString("driverName"); 
     URL = config.getString("url"); 
     UNAME = config.getString("uname"); 
     PWD = config.getString("pwd"); 

     dataSource = setupDataSource(); 
    } 

    public static Connection getOracleConnection() throws SQLException { 
     return dataSource.getConnection(); 
    } 

    private static DataSource setupDataSource() { 
     ComboPooledDataSource cpds = new ComboPooledDataSource(); 
     try { 
      cpds.setDriverClass(DRIVER_NAME); 
     } catch (PropertyVetoException e) { 
      e.printStackTrace(); 
     } 
     cpds.setJdbcUrl(URL); 
     cpds.setUser(UNAME); 
     cpds.setPassword(PWD); 
     cpds.setMinPoolSize(5); 
     cpds.setAcquireIncrement(5); 
     cpds.setMaxPoolSize(20); 
     return cpds; 
    } 
} 

en el DAO Voy a escribir algo como esto:

try { 
      conn = DBConnection.getOracleConnection(); 

      .... 


} finally { 
    try { 
     if (rs != null) { 
      rs.close(); 
     } 
     if (ps != null) { 
      ps.close(); 
     } 
     if (conn != null) { 
      conn.close(); 
     } 
    } catch (SQLException e) { 
     logger 
       .logError("Exception occured while closing cursors!", e); 

    } 

Ahora, mi pregunta es qué me molesto en hacer cualquier otra limpiar aparte de cerrar los cursores (conexión/declaración/resultSet/preparedStatement) listado en el bloque finally.

¿Qué es this cleanup ?? ¿Cuándo y dónde debería hacer esto?

En caso de encontrar algo incorrecto en el código anterior, por favor, señalan.

+0

en JDK 7 no es necesario cerrar preparedStatement, implementa AutoClosable. [debido a esta publicación] (http://stackoverflow.com/questions/14862853/resource-leak-warning-in-eclipse) –

Respuesta

20

Con una fuente de datos combinada, las conexiones en la agrupación no están realmente cerradas, simplemente se devuelven al grupo. Sin embargo, cuando la aplicación se cierra, las conexiones a la base de datos deben ser correctamente y de hecho estaba cerrado, que es donde la limpieza final entra en acción.

Por cierto, el proyecto c3p0 está prácticamente muerta en el agua, se lo recomiendo use Apache Commons DBCP en su lugar, aún se mantiene.

+7

@skaffman: Estaba a punto de cambiar de DBCP a C3P0 después de leer casi lo contrario a lo que usted ha dicho aquí: http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0. Ahora no estoy tan seguro. Parece que ninguno de los proyectos ha tenido mucho TLC recientemente. – Adamski

+0

@ Adamski: Te escucho. Brecha definitiva en el mercado allí. – skaffman

+2

Utilice BoneCP, herramienta muy activa, excelente, buena documentación, muy rápido. Lo usamos en sitios de mucho tráfico y no tenemos problemas. – Janning

3

El código me parece bien, pero escribiría un método de ayuda que realiza las operaciones de cierre o obtendrá este detallado bloque finalmente en cada DAO o método. Tal vez debería escribir tres separados try-catch-bloques en torno a las operaciones de cierre, para asegurarse de que la conexión se cierra, no importa si la declaración de resultados y han lanzado un exection. También tenga en cuenta que javadoc says

Cuando se cierra un objeto Statement, su objeto actual ResultSet, si existe, también se cierra.

Así que no necesita cerrar el conjunto de resultados en el ejemplo anterior, pero podría.

El método de limpieza vinculado es para cerrar el origen de datos, lo que no se necesita en la mayoría de los proyectos porque el DS vive mientras se ejecuta la aplicación.

5

DAOs no debe ser responsable de la adquisición de una conexión a la base de datos. No tienen forma de saber cuándo se usan como parte de una transacción más grande. Debería pasar la fuente de datos o la instancia de conexión al DAO.

Si alguna de las llamadas para cerrar en su bloque finally arroja una excepción, no se ejecutará ninguna de las siguientes. Cada uno necesita estar en su propio bloque try/catch. Los puse en una clase de utilidad como métodos estáticos.

0

utilizo Marco de Juego y Scala, por lo que el siguiente ejemplo es en el proyecto de obra.

Paso 1. configuración

En build.sbt, si usa mysql/hive como base de datos, necesita agregar estas propiedades.

libraryDependencies ++ = Seq (
    jdbc, 
    "mysql" % "mysql-connector-java" % "5.1.31", 
    "org.apache.hive" % "hive-jdbc" % "0.12.0", 
    "com.mchange" % "c3p0" % "0.9.2.1" 
) 

Step2. cómo acceder a ella? necesita importar la biblioteca c3p0.

import com.mchange.v2.c3p0.ComboPooledDataSource 

Step3. y luego necesitas crear una instancia.

val cpds = new ComboPooledDataSource() 
cpds.setDriverClass(...) 
cpds.setJdbcUrl(...) 
cpds.setUser(...) 
cpds.setPassword(...) 

Step4. obtienes una conexión

cpds.getConnection 
Cuestiones relacionadas