2013-05-01 236 views
2

我正在使用一个库,我需要获取数据源并将其提供给它。无论如何,我可以从连接池中获得连接吗?我正在使用Hibernate 4和C3p0连接池。从C3P0连接池获取数据源/连接

,这里是我的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> 

     <!-- Database connection settings --> 

     <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="connection.url">jdbc:mysql://localhost:3306/sampleDB</property> 
     <property name="connection.username">root</property> 
     <property name="connection.password">mypass</property> 

     <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 
     <property name="c3p0.max_size">100</property> 
     <property name="c3p0.min_size">1</property> 
     <property name="c3p0.idle_test_period">30</property> 

     <!-- SQL dialect --> 
     <property name="dialect"> 
      org.hibernate.dialect.MySQLDialect 
     </property> 

     <!-- Shows Generated SQL Queries By Hibernate --> 
     <property name="show_sql">false</property> 

     <!-- Drop and re-create The Database Schema on Start up --> 
     <property name="hbm2ddl.auto">update</property> 

     <property name="cache.provider.class">org.hibernate.cache.NoCacheProvider</property> 


    </session-factory> 

</hibernate-configuration> 

回答

3

如果您正在使用hibernate并希望访问它已在使用的c3p0连接池,则一种简单的方法是使用C3P0Registry类查找数据源,请参阅herehere

您可能会发现getPooledDataSources()返回一个包含单个元素的Set,并且这将是Hibernate构造的DataSource。如果你愿意,你也可以设置配置参数c3p0.dataSourceName(在hibernate配置中的hibernate.c3p0.dataSourceName),并使用C3P0Registry.pooledDataSourcesByName(dataSourceName)。

[如果您要设置自己的名称,那么可能需要验证hibernate没有使用dataSourceName属性本身。我不认为它确实如此,但我没有检查。检查最简单的方法是查看日志中的init config pool dump,并确保其中包含“dataSourceName - > z8kflt8uqkl8iymaxxkw | 729f44”。如果这个名字是一个很长的random-ish字符串,并且有一个管道,那么它就是一个特定于实例的自动生成的身份标记,您应该随意设置自己的名字。如果你看到一个更明智的名字,那么hibernate已经设置了这个属性,并且可能期待你看到的名字,所以你应该查找这个名字。]

请注意,如果你打算直接使用来自DataSource的连接,注意确保所有连接在finally块中正确关闭()。如果你“泄漏”连接,即如果你检查出它们并且无法可靠地检查它们,你最终会耗尽池并冻结你的休眠应用程序。

祝你好运!

更新:例...

import java.util.Set; 
import javax.sql.DataSource; 
import com.mchange.v2.c3p0.C3P0Registry; 

// you probably want better Exception handling than this... 
private DataSource findUniqueDataSource() 
{ 
    Set set = C3P0Registry.getPooledDataSources(); 
    int sz = set.size(); 
    if (sz == 1) // yay, just one DataSource 
     return (DataSource) set.iterator().next(); 
    else 
     throw new RuntimeException("No unique c3p0 DataSource, found:" + sz); 
} 

// be sure you have configured a dataSourceName in your c3p0 or hibernate config 
private DataSource findDataSourceByName(String dataSourceName) 
{ return C3P0Registry.pooledDataSourceByName(dataSourceName); } 

不,你不应该“泄漏”连接,并期望池后面进行清理。您可以忘记关闭语句和结果集,并且在关闭连接时池会关闭它们,但池不知道可以安全地从连接失败的客户端抓取连接它。有些应用程序长时间保持连接打开状态(尽管如果您使用的是连接缓冲池,那么这是不好的做法)。

您可以强制 c3p0在一段时间后清理泄漏的连接,请参阅配置参数unreturnedConnectionTimeout。但这是一个棘手的策略;我建议如果您有泄漏,只能暂时与debugUnreturnedConnectionStackTraces一起使用,以了解您连接泄漏的位置,然后解决问题。

+0

你能举例说明如何做到这一点吗?如果我“泄漏”连接,我认为它会自动关闭? – user962206 2013-05-01 11:16:06

+0

查看上面的更新。 – 2013-05-01 11:55:59

+0

谢谢,虽然我目前正在使用它来设置我的c3p0连接,https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool在哪里可以设置dataSourceName?你的findUniqueDataSource有什么用处?为什么我可以直接使用findDataSourceByName? – user962206 2013-05-01 12:00:46

0

C3P0提供连接池对Hibernate,为内置的Hibernate连接池不用于产品使用。它缺少在任何体面的连接池上发现的几个功能 - 根据Hibernate Community Documentation,对于使用Hibernate配置c3p0,可以参考thisMKYong关于Hibernate Community的教程。

+0

我已经使用第一个链接配置了我的C3P0连接池,无论如何,我可以从连接池中获得连接/数据源?因为我将需要它并将其传递到我的代码中的某处。 – user962206 2013-05-01 11:12:19