原文引自:http://www.matrix.org.cn/thread.shtml?topicId=33623&forumId=23
1:net.sf.hibernate.connection
此包中的类为提供数据源连接池的类,其中用到了C3P0,DBCP,DriverManager等第三方连接池插件;
其中ConnectionProvider为一致对外接口;所有的功能类都实现的他的接口;
/**
* Initialize the connection provider from given properties.
* @param props <tt>SessionFactory</tt> properties
*/
public void configure(Properties props) throws HibernateException;
/**
* Grab a connection
* @return a JDBC connection
* @throws SQLException
*/
public Connection getConnection() throws SQLException;
/**
* Dispose of a used connection.
* @param conn a JDBC connection
* @throws SQLException
*/
public void closeConnection(Connection conn) throws SQLException;
/**
* Release all resources held by this provider. JavaDoc requires a second sentence.
* @throws HibernateException
*/
public void close() throws HibernateException;
源码中的注释把方法功能描述的很具体,我再次就不再加介绍了,现在具体的拿出两个实现类来具体看一下他的功能;
1.1 C3P0ConnectionProvider implements ConnectionProvider
public void configure(Properties props) throws HibernateException {
//获取数据库的驱程和URL;
String jdbcDriverClass = props.getProperty(Environment.DRIVER);
String jdbcUrl = props.getProperty(Environment.URL);
//对第三方插件所需要的属性进行定制包装;
Properties connectionProps = ConnectionProviderFactory.getConnectionProperties(props);
log.info("C3P0 using driver: " + jdbcDriverClass + " at URL: " + jdbcUrl);
log.info("Connection properties: " + connectionProps);
//加载数据库驱动程序
if (jdbcDriverClass==null) {
log.warn("No JDBC Driver class was specified by property " + Environment.DRIVER);
}
else {
try {
Class.forName(jdbcDriverClass);
}
catch (ClassNotFoundException cnfe) {
String msg = "JDBC Driver class not found: " + jdbcDriverClass;
log.fatal(msg);
throw new HibernateException(msg);
}
}
try {
//加载配置文件中的properties;
int minPoolSize = PropertiesHelper.getInt(Environment.C3P0_MIN_SIZE, props, 1);
int maxPoolSize = PropertiesHelper.getInt(Environment.C3P0_MAX_SIZE, props, 100);
int maxIdleTime = PropertiesHelper.getInt(Environment.C3P0_TIMEOUT, props, 0);
int maxStatements = PropertiesHelper.getInt(Environment.C3P0_MAX_STATEMENTS, props, 0);
int acquireIncrement = PropertiesHelper.getInt(Environment.C3P0_ACQUIRE_INCREMENT, props, 1);
int idleTestPeriod = PropertiesHelper.getInt(Environment.C3P0_IDLE_TEST_PERIOD, props, 0);
boolean validateConnection = PropertiesHelper.getBoolean(Environment.C3P0_VALIDATE_CONNECTION, props);
//有C3P0的连接池接口来设置第三方插件所需要的属性
此处为与第三方插件的结合点;
PoolConfig pcfg = new PoolConfig();
pcfg.setInitialPoolSize(minPoolSize);
pcfg.setMinPoolSize(minPoolSize);
pcfg.setMaxPoolSize(maxPoolSize);
pcfg.setAcquireIncrement(acquireIncrement);
pcfg.setMaxIdleTime(maxIdleTime);
pcfg.setMaxStatements(maxStatements);
pcfg.setTestConnectionOnCheckout(validateConnection);
pcfg.setIdleConnectionTestPeriod(idleTestPeriod);
//用第三方插件来初始化连接池,并向程序返回了JDBC的DataSource接口,使得任何第三方插件的上层程序都不必去引入相应具体的第三方的类库,实现的低耦合;
/*DataSource unpooled = DataSources.unpooledDataSource(
jdbcUrl, props.getProperty(Environment.USER), props.getProperty(Environment.PASS)
);*/
DataSource unpooled = DataSources.unpooledDataSource(jdbcUrl, connectionProps);
ds = DataSources.pooledDataSource(unpooled, pcfg);
}
catch (Exception e) {
log.fatal("could not instantiate C3P0 connection pool", e);
throw new HibernateException("Could not instantiate C3P0 connection pool", e);
}
String i = props.getProperty(Environment.ISOLATION);
if (i==null) {
isolation=null;
}
else {
isolation = new Integer(i);
log.info( "JDBC isolation level: " + Environment.isolationLevelToString( isolation.intValue() ) );
}
}
public Connection getConnection() throws SQLException {
final Connection c = ds.getConnection();
//设置事务的隔离级别;
if (isolation!=null) c.setTransactionIsolation( isolation.intValue() );
if ( c.getAutoCommit() ) c.setAutoCommit(false);
return c;
}
public void closeConnection(Connection conn) throws SQLException {
conn.close();
}
public void close() {
try {
DataSources.destroy(ds);
}
catch (SQLException sqle) {
log.warn("could not destroy C3P0 connection pool", sqle);
}
}
1.2 class DriverManagerConnectionProvider implements ConnectionProvider
public void configure(Properties props) throws HibernateException {
String driverClass = props.getProperty(Environment.DRIVER);
poolSize = PropertiesHelper.getInt(Environment.POOL_SIZE, props, 20); //default pool size 20
log.info("Using Hibernate built-in connection pool (not for production use!)");
log.info("Hibernate connection pool size: " + poolSize);
isolation = PropertiesHelper.getInteger(Environment.ISOLATION, props);
if (isolation!=null)
log.info( "JDBC isolation level: " + Environment.isolationLevelToString( isolation.intValue() ) );
if (driverClass==null) {
log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
}
else {
try {
// trying via forName() first to be as close to DriverManager's semantics
Class.forName(driverClass);
}
catch (ClassNotFoundException cnfe) {
try {
ReflectHelper.classForName(driverClass);
} catch (ClassNotFoundException e) {
String msg = "JDBC Driver class not found: " + driverClass;
log.fatal(msg);
throw new HibernateException(msg);
}
}
}
url = props.getProperty(Environment.URL);
if (url==null) {
String msg = "JDBC URL was not specified by property " + Environment.URL;
log.fatal(msg);
throw new HibernateException(msg);
}
connectionProps = ConnectionProviderFactory.getConnectionProperties(props);
log.info( "using driver: " + driverClass + " at URL: " + url );
log.info("connection properties: " + connectionProps);
}
public Connection getConnection() throws SQLException {
if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );
//锁死连接池,只需一个线程访问,池中有连接就提供,没有在新建一个;
synchronized (pool) {
if ( !pool.isEmpty() ) {
int last = pool.size() - 1;
if ( log.isTraceEnabled() ) {
log.trace("using pooled JDBC connection, pool size: " + last);
checkedOut++;
}
Connection pooled = (Connection) pool.remove(last);
if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
if ( pooled.getAutoCommit() ) pooled.setAutoCommit(false);
return pooled;
}
}
log.debug("opening new JDBC connection");
Connection conn = DriverManager.getConnection(url, connectionProps);
if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
if ( conn.getAutoCommit() ) conn.setAutoCommit(false);
if ( log.isDebugEnabled() ) {
log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
}
if ( log.isTraceEnabled() ) checkedOut++;
return conn;
}
public void closeConnection(Connection conn) throws SQLException {
if ( log.isDebugEnabled() ) checkedOut--;
//如果池中连接已满就释放连接,否则就加到连接池中;
synchronized (pool) {
int currentSize = pool.size();
if ( currentSize < poolSize ) {
if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );
pool.add(conn);
return;
}
}
log.debug("closing JDBC connection");
try {
conn.close();
}
catch (SQLException sqle) {
JDBCExceptionReporter.logExceptions(sqle);
throw sqle;
}
}
public void close() {
//清空连接池;
log.info("cleaning up connection pool: " + url);
Iterator iter = pool.iterator();
while ( iter.hasNext() ) {
try {
( (Connection) iter.next() ).close();
}
catch (SQLException sqle) {
log.warn("problem closing pooled connection", sqle);
}
}
pool.clear();
}