2013-05-01 152 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