2

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

2 回答 2

3

如果您正在使用休眠并且想要访问它已经在使用的 c3p0 连接池,一种简单的方法是使用 C3P0Registry 类来查找数据源,请参见此处此处

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

[如果您要设置自己的名称,则可能值得验证 hibernate 没有使用 dataSourceName 属性本身。我不认为它确实如此,但我没有检查过。最简单的检查方法是在 init 上查看池配置转储的日志,并确保其中有类似“dataSourceName -> 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); }

不,您不应该“泄漏”连接并期望池在您之后清理。您可以忘记关闭语句和结果集,当您关闭()连接时,池会处理它们,但是池不知道何时可以安全地从未能关闭它的客户端抢回连接。某些应用程序会长时间保持连接打开(尽管如果您使用的是连接池,那是不好的做法)。

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

于 2013-05-01T11:09:56.020 回答
0

c3p0 为 Hibernate 提供连接池,因为内置的 Hibernate 连接池绝不是用于生产用途的。它缺少在任何体面的连接池上发现的几个功能- 根据Hibernate 社区文档,对于使用 Hibernate 配置 c3p0,您可以参考 Hibernate 社区上的这个MKYong教程。

于 2013-05-01T10:53:05.473 回答