HibernateでDBCP接続プールを設定する方法
今、http://commons.apache.org/dbcp/[Apache DBCP]は活発な開発に戻っており、多くのバグは修正されており、現在はより安定しています。 Hibernateでも、http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/connection/C3P0ConnectionProvider.html[C3P0]やhttp://docs.jboss.orgのような接続プロバイダは付属していません/hibernate/core/3.6/javadocs/org/hibernate/connection/ProxoolConnectionProvider.html[Proxool]でも簡単に設定できます。
このチュートリアルでは、Apache DBCP接続プールとHibernateフレームワークを統合する方法を説明します。
1. DBCP jarを取得する
DBCPとHibernateを統合するには、
commons-dbcp.jar
と
commons-pool-1.5.4.jar
が必要です。
File:pom.xml
<project ...> <repositories> <repository> <id>JBoss repository</id> <url>http://repository.jboss.org/nexus/content/groups/public/</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.3.Final</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> </dependencies> </project>
2. DBCPConnectionProvider
DBCPとHibernateを統合するには、 ”
DBCPConnectionProvider
“クラスを作成する必要があります。このクラスはhttp://wiki.apache.org/commons/DBCP/Hibernate[articleを参照してください。
ファイル:DBCP Connection Provider.java
package com.mkyong.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. hibernate.cfg.xmlにDBCPを設定する
ここで、 ”
DBCPConnectionProvider
“をリンクし、 ”
hibernate.cfg.xml
“にDBCPプロパティを定義します。
File:hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver__class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:MKYONG</property> <property name="hibernate.connection.username">mkyong</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> <property name="hibernate.default__schema">MKYONG</property> <property name="show__sql">true</property> <property name="hibernate.connection.provider__class"> com.mkyong.util.DBCPConnectionProvider </property> <property name="hibernate.dbcp.initialSize">8</property> <property name="hibernate.dbcp.maxActive">20</property> <property name="hibernate.dbcp.maxIdle">20</property> <property name="hibernate.dbcp.minIdle">0</property> <mapping class="com.mkyong.user.DBUser"></mapping> </session-factory> </hibernate-configuration>
-
注意
DBCPプロパティは、Hibernateで ”
hibernate.dbcp.properties-name ** “を介してサポートされています。
すべてのDBCPプロパティについては、http://commons.apache.org/dbcp/configuration.html[DBCP設定]ページを参照してください。
4.それを実行し、出力します.
完了して、次の出力を参照してください。
アプリケーションの起動段階では、8つのデータベース接続が接続プールに作成され、Webアプリケーションで使用できる状態になります。
それをダウンロードしてください://wp-content/uploads/2011/04/Hibernate-DBCP-Connection-Pool-Example.zip[Hibernate-DBCP-Connection-Pool-Example.zip](10KB)