Comment configurer le pool de connexions DBCP dans Hibernate

Comment configurer le pool de connexions DBCP dans Hibernate

Note
En raison de bogues dans l'ancien code DBCP, Hibernate ne gère plus le fournisseur de connexion basé sur DBCP, lisez ceciHibernate thread.

Maintenant,Apache DBCP est de retour au développement actif, et de nombreux bogues sont corrigés et il est plus stable maintenant. Même Hibernate n'est pas fourni avec un fournisseur de connexion commeC3P0 etProxool, mais vous pouvez toujours le configurer facilement.

Dans ce didacticiel, nous vous montrons comment intégrer le pool de connexions Apache DBCP au framework Hibernate.

1. Obtenez des bocaux DBCP

Pour intégrer DBCP à Hibernate, vous avez besoin decommons-dbcp.jar etcommons-pool-1.5.4.jar.

Fichier: pom.xml



    
        
            JBoss repository
            http://repository.jboss.org/nexus/content/groups/public/
        
    

    

        
            org.hibernate
            hibernate-core
            3.6.3.Final
        

        
            commons-dbcp
            commons-dbcp
            1.4
        

    

2. DBCPConnectionProvider

Pour intégrer DBCP à Hibernate, vous devez créer une classe «DBCPConnectionProvider», reportez-vous à cearticle.

Fichier: DBCPConnectionProvider.java

package com.example.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.connection.ConnectionProviderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DBCPConnectionProvider implements ConnectionProvider {

    private static final Logger log = LoggerFactory
            .getLogger(DBCPConnectionProvider.class);
    private static final String PREFIX = "hibernate.dbcp.";
    private BasicDataSource ds;

    // Old Environment property for backward-compatibility (property removed in
    // Hibernate3)
    private static final String DBCP_PS_MAXACTIVE = "hibernate.dbcp.ps.maxActive";

    // Property doesn't exists in Hibernate2
    private static final String AUTOCOMMIT = "hibernate.connection.autocommit";

    public void configure(Properties props) throws HibernateException {
        try {
            log.debug("Configure DBCPConnectionProvider");

            // DBCP properties used to create the BasicDataSource
            Properties dbcpProperties = new Properties();

            // DriverClass & url
            String jdbcDriverClass = props.getProperty(Environment.DRIVER);
            String jdbcUrl = props.getProperty(Environment.URL);
            dbcpProperties.put("driverClassName", jdbcDriverClass);
            dbcpProperties.put("url", jdbcUrl);

            // Username / password
            String username = props.getProperty(Environment.USER);
            String password = props.getProperty(Environment.PASS);
            dbcpProperties.put("username", username);
            dbcpProperties.put("password", password);

            // Isolation level
            String isolationLevel = props.getProperty(Environment.ISOLATION);
            if ((isolationLevel != null)
                    && (isolationLevel.trim().length() > 0)) {
                dbcpProperties.put("defaultTransactionIsolation",
                        isolationLevel);
            }

            // Turn off autocommit (unless autocommit property is set)
            String autocommit = props.getProperty(AUTOCOMMIT);
            if ((autocommit != null) && (autocommit.trim().length() > 0)) {
                dbcpProperties.put("defaultAutoCommit", autocommit);
            } else {
                dbcpProperties.put("defaultAutoCommit",
                        String.valueOf(Boolean.FALSE));
            }

            // Pool size
            String poolSize = props.getProperty(Environment.POOL_SIZE);
            if ((poolSize != null) && (poolSize.trim().length() > 0)
                    && (Integer.parseInt(poolSize) > 0)) {
                dbcpProperties.put("maxActive", poolSize);
            }

            // Copy all "driver" properties into "connectionProperties"
            Properties driverProps = ConnectionProviderFactory
                    .getConnectionProperties(props);
            if (driverProps.size() > 0) {
                StringBuffer connectionProperties = new StringBuffer();
                for (Iterator iter = driverProps.entrySet().iterator(); iter
                        .hasNext();) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String key = (String) entry.getKey();
                    String value = (String) entry.getValue();
                    connectionProperties.append(key).append('=').append(value);
                    if (iter.hasNext()) {
                        connectionProperties.append(';');
                    }
                }
                dbcpProperties.put("connectionProperties",
                        connectionProperties.toString());
            }

            // Copy all DBCP properties removing the prefix
            for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) {
                Map.Entry entry = (Map.Entry) iter.next();
                String key = (String) entry.getKey();
                if (key.startsWith(PREFIX)) {
                    String property = key.substring(PREFIX.length());
                    String value = (String) entry.getValue();
                    dbcpProperties.put(property, value);
                }
            }

            // Backward-compatibility
            if (props.getProperty(DBCP_PS_MAXACTIVE) != null) {
                dbcpProperties.put("poolPreparedStatements",
                        String.valueOf(Boolean.TRUE));
                dbcpProperties.put("maxOpenPreparedStatements",
                        props.getProperty(DBCP_PS_MAXACTIVE));
            }

            // Some debug info
            if (log.isDebugEnabled()) {
                StringWriter sw = new StringWriter();
                dbcpProperties.list(new PrintWriter(sw, true));
                log.debug(sw.toString());
            }

            // Let the factory create the pool
            ds = (BasicDataSource) BasicDataSourceFactory
                    .createDataSource(dbcpProperties);

            // The BasicDataSource has lazy initialization
            // borrowing a connection will start the DataSource
            // and make sure it is configured correctly.
            Connection conn = ds.getConnection();
            conn.close();

            // Log pool statistics before continuing.
            logStatistics();
        } catch (Exception e) {
            String message = "Could not create a DBCP pool";
            log.error(message, e);
            if (ds != null) {
                try {
                    ds.close();
                } catch (Exception e2) {
                    // ignore
                }
                ds = null;
            }
            throw new HibernateException(message, e);
        }
        log.debug("Configure DBCPConnectionProvider complete");
    }

    public Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            conn = ds.getConnection();
        } finally {
            logStatistics();
        }
        return conn;
    }

    public void closeConnection(Connection conn) throws SQLException {
        try {
            conn.close();
        } finally {
            logStatistics();
        }
    }

    public void close() throws HibernateException {
        log.debug("Close DBCPConnectionProvider");
        logStatistics();
        try {
            if (ds != null) {
                ds.close();
                ds = null;
            } else {
                log.warn("Cannot close DBCP pool (not initialized)");
            }
        } catch (Exception e) {
            throw new HibernateException("Could not close DBCP pool", e);
        }
        log.debug("Close DBCPConnectionProvider complete");
    }

    protected void logStatistics() {
        if (log.isInfoEnabled()) {
            log.info("active: " + ds.getNumActive() + " (max: "
                    + ds.getMaxActive() + ")   " + "idle: " + ds.getNumIdle()
                    + "(max: " + ds.getMaxIdle() + ")");
        }
    }

    public boolean supportsAggressiveRelease() {
        return false;
    }
}

3. Configurer DBCP dans hibernate.cfg.xml

Maintenant, liez vos «DBCPConnectionProvider» et définissez les propriétés DBCP dans «hibernate.cfg.xml», par exemple:

Fichier: hibernate.cfg.xml



 
  oracle.jdbc.driver.OracleDriver
  jdbc:oracle:thin:@localhost:1521:MKYONG
  example
  password
  org.hibernate.dialect.Oracle10gDialect
  MKYONG
  true

  
    com.example.util.DBCPConnectionProvider
  
  8
  20
  20
  0

  

Note
Les propriétés DBCP sont prises en charge dans Hibernate via «hibernate.dbcp.properties-name».

Pour toutes les propriétés DBCP, veuillez vous référer à cette pageDBCP configuration.

4. Exécutez-le, sortie

Terminé, exécutez-le et voyez la sortie suivante:

dbcp connection pool in hibernate

Lors de la phase de démarrage de l'application, 8 connexions à la base de données sont créées dans le pool de connexions, prêtes à être utilisées par votre application Web.

Téléchargez-le -Hibernate-DBCP-Connection-Pool-Example.zip (10 Ko)