java - star - Agrupación de conexiones JDBC utilizando C3P0
pool de conexiones sql server (4)
La siguiente es mi clase de ayuda para obtener la conexión de base de datos:
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 estaré escribiendo 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 si debo molestarme en hacer cualquier otra limpieza que no sea cerrar los cursores (conexión / declaración / resultado / configuración / preparado) en el bloque final.
¿Qué es this limpieza? ¿Cuándo y dónde debo hacer esto?
Si encuentra algo incorrecto en el código anterior, indíquelo.
Con un origen de datos agrupados, las conexiones en el conjunto no están realmente cerradas, simplemente se devuelven al conjunto. Sin embargo, cuando la aplicación se apaga, esas conexiones a la base de datos deben estar correctamente cerradas, que es donde entra la limpieza final.
Por cierto, el proyecto c3p0 está bastante muerto en el agua, le recomiendo que use Apache Commons DBCP en su lugar, aún se mantiene.
El código me parece bien, pero escribiría un método auxiliar que realice las operaciones de cierre o obtendrá este bloque detallado por fin en cada DAO o método. Tal vez debería escribir tres try-catch-blocks separados alrededor de las Operaciones de cierre, para asegurarse de que la conexión esté cerrada sin importar si la declaración y el conjunto de resultados han arrojado una excepción. También tenga en cuenta que el javadoc dice
Cuando se cierra un objeto Statement, su objeto ResultSet actual, si existe, también se cierra.
Por lo tanto, no necesita cerrar el conjunto de resultados en el ejemplo anterior, pero podría hacerlo.
El método de limpieza vinculado es para cerrar la fuente de datos, lo que no es necesario en la mayoría de los proyectos porque el DS permanece activo mientras su aplicación se esté ejecutando.
Los DAO no deben ser responsables de adquirir una conexión a la base de datos. No tienen forma de saber cuándo se están utilizando como parte de una transacción más grande. Debería pasar el origen de datos o la instancia de conexión al DAO.
Si alguna de las llamadas a cerrar en su bloque finalmente lanza una excepción, no se llamará a ninguna de las siguientes. Cada uno debe estar en su propio bloque try / catch. Los puse en una clase de utilidad como métodos estáticos.
Uso Play Framework y Scala, por lo que el siguiente ejemplo está en el proyecto Play.
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"
)
Paso 2. ¿Cómo acceder a él? necesitas importar la librería c3p0.
import com.mchange.v2.c3p0.ComboPooledDataSource
Paso 3. y luego necesita crear instancia.
val cpds = new ComboPooledDataSource()
cpds.setDriverClass(...)
cpds.setJdbcUrl(...)
cpds.setUser(...)
cpds.setPassword(...)
Etapa 4. obtienes una conexión
cpds.getConnection