web-dev-qa-db-fra.com

Regroupement de connexions JDBC à l'aide de C3P0

Voici ma classe d'assistance pour obtenir une connexion à la base de données:

J'ai utilisé le regroupement de connexions C3P0 comme décrit ici .

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;
    }
}

dans le DAO, je vais écrire quelque chose comme ceci:

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);

    }

Ma question est la suivante: devrais-je prendre la peine d’effectuer un autre nettoyage autre que la fermeture des curseurs (connection/statement/resultSet/prepareStatement) répertoriés dans le bloc finally.

Qu'est-ce que ceci nettoyage ?? Quand et où devrais-je faire cela?

Si vous rencontrez un problème dans le code ci-dessus, veuillez le signaler.

28
jai

Avec une source de données en pool, les connexions du pool ne sont pas réellement fermées, elles sont simplement renvoyées au pool. Cependant, lorsque l'application est fermée, ces connexions à la base de données doivent être correctement et réellement fermées, c'est là qu'intervient le nettoyage final.

Incidemment, le projet c3p0 est pratiquement mort dans l’eau, je vous recommande d’utiliser Apache Commons DBCP au lieu de cela, il est toujours maintenu.

23
skaffman

Les DAO ne devraient pas être responsables de l’acquisition d’une connexion à la base de données. Ils n'ont aucun moyen de savoir quand ils sont utilisés dans le cadre d'une transaction plus importante. Vous devez transmettre la source de données ou l'instance de connexion à la DAO.

Si l'un des appels à fermer dans votre dernier bloc génère une exception, aucun des appels suivants ne sera appelé. Chacun doit être dans son propre bloc try/catch. Je les mets dans une classe d'utilitaire en tant que méthodes statiques.

6
duffymo

Le code me semble bien, mais j'écrirais une méthode d'assistance qui effectue les opérations de fermeture ou vous obtiendrez ce blocage-détaillé verbose dans chaque DAO ou méthode. Vous devriez peut-être écrire trois blocs try-catch distincts autour des opérations de fermeture, pour vous assurer que la connexion est fermée, peu importe si l'instruction et le jeu de résultats ont déclenché une exection. Notez également que le javadoc dit

Lorsqu'un objet Statement est fermé, son objet ResultSet actuel, s'il en existe un, est également fermé. 

Vous n'avez donc pas besoin de fermer le jeu de résultats dans l'exemple ci-dessus, mais vous pouvez le faire.

La méthode de nettoyage liée permet de fermer la source de données, ce qui n'est pas nécessaire dans la plupart des projets car le DS est actif tant que votre application est en cours d'exécution.

5
Tim Büthe

J'utilise Play Framework et Scala. L'exemple suivant est donc dans le projet play.

Étape 1. configuration

Dans build.sbt, si vous utilisez mysql/Hive comme base de données, vous devez ajouter ces propriétés. 

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"
)

Étape 2. comment y accéder? vous devez importer la bibliothèque c3p0.

import com.mchange.v2.c3p0.ComboPooledDataSource

Étape 3. et vous devez ensuite créer une instance.

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

Étape 4. vous obtenez une connexion

cpds.getConnection
0
Haimei