我正在使用一个库,我需要获取数据源并将其提供给它。无论如何我可以从连接池获得连接?我正在使用带有C3p0连接池的Hibernate 4。
这是我的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>
答案 0 :(得分:3)
如果您正在使用hibernate并且想要访问它已经使用的c3p0连接池,一种简单的方法是使用C3P0Registry类来查找DataSource,请参阅here和here。
可能你会发现getPooledDataSources()返回一个包含单个元素的Set,这将是hibernate构造的DataSource。如果你愿意,你也可以设置config param c3p0.dataSourceName(hibernate配置中的hibernate.c3p0.dataSourceName),并使用C3P0Registry.pooledDataSourcesByName(dataSourceName)。
[如果您将设置自己的名称,则可能值得验证hibernate未使用dataSourceName属性本身。我不认为它确实如此,但我没有检查过。最简单的检查方法是查看init上的池配置转储日志,并确保其中包含“dataSourceName - &gt; z8kflt8uqkl8iymaxxkw | 729f44”。如果名称是一个长随机字符串,其中包含管道,则它是特定于实例的自动生成的标识令牌,您可以随意设置自己的名称。如果你看到一个更明智的名字,那么hibernate已经设置了这个属性,并且可能期望你看到的名字,所以你应该查找那个名字。]
请注意,如果您计划直接使用DataSource中的Connections,请注意确保所有Connections在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); }
不,你不应该“泄漏”连接并希望游戏池在你之后清理。您可以忘记关闭语句和结果集,并且当您关闭()连接时池将处理它们,但是当时,池不知道从客户端抢夺Connection是安全的没有关闭它。某些应用程序长时间保持连接打开(尽管这是不好的做法,如果您使用的是连接池)。
您可以强制 c3p0在一段时间后清除泄露的Connections,请参阅config参数unreturnedConnectionTimeout。但这是一个狡猾的策略;我建议您是否有泄漏,只能暂时与debugUnreturnedConnectionStackTraces一起使用,以了解泄漏连接的位置,然后解决问题。
答案 1 :(得分:0)
c3p0为Hibernate提供连接池,因为内置的Hibernate连接池绝对不能用于生产。它没有在任何体面的连接池上找到的几个功能 - 根据Hibernate Community Documentation,对于使用Hibernate配置c3p0,您可以参考Hibernate社区的this或MKYong教程。 / p>