从C3P0连接池获取DataSource / Connection

时间:2013-05-01 10:24:23

标签: java hibernate datasource connection-pooling c3p0

我正在使用一个库,我需要获取数据源并将其提供给它。无论如何我可以从连接池获得连接?我正在使用带有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>

2 个答案:

答案 0 :(得分:3)

如果您正在使用hibernate并且想要访问它已经使用的c3p0连接池,一种简单的方法是使用C3P0Registry类来查找DataSource,请参阅herehere

可能你会发现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社区的thisMKYong教程。 / p>