Spring_c3p0 配置詳解



<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:jee="http://www.springframework.org/schema/jee"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">

<bean id="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

<property name="driverClass">

<value>com.mysql.jdbc.Driver</value>

</property>

<property name="jdbcUrl">

<value>jdbc:mysql://192.168.3.110:3306/DBName?useUnicode=true&amp;characterEncoding=GBK</value>

</property>

<property name="user">

<value>root</value>

</property>

<property name="password">

<value>root</value>

</property>

<!--連接池中保留的最小連接數。-->

<property name="minPoolSize">

<value>5</value>

</property>

<!--連接池中保留的最大連接數。Default: 15 -->

<property name="maxPoolSize">

<value>30</value>

</property>

<!--初始化時獲取的連接數,取值應在minPoolSize與maxPoolSize之間。Default: 3 -->

<property name="initialPoolSize">

<value>10</value>

</property>

<!--最大空閒時間,60秒內未使用則連接被丟棄。若爲0則永不丟棄。Default: 0 -->

<property name="maxIdleTime">

<value>60</value>

</property>

<!--當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3 -->

<property name="acquireIncrement">

<value>5</value>

</property>

<!--JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但由於預緩存的statements

屬於單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。

如果maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default: 0-->

<property name="maxStatements">

<value>0</value>

</property>

<!--每60秒檢查所有連接池中的空閒連接。Default: 0 -->

<property name="idleConnectionTestPeriod">

<value>60</value>

</property>

<!--定義在從數據庫獲取新連接失敗後重復嘗試的次數。Default: 30 -->

<property name="acquireRetryAttempts">

<value>30</value>

</property>

<!--獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效

保留,並在下次調用getConnection()的時候繼續嘗試獲取連接。如果設爲true,那麼在嘗試

獲取連接失敗後該數據源將申明已斷開並永久關閉。Default: false-->

<property name="breakAfterAcquireFailure">

<value>true</value>

</property>

<!--因性能消耗大請只在需要的時候使用它。如果設爲true那麼在每個connection提交的

時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable

等方法來提升連接測試的性能。Default: false -->

<property name="testConnectionOnCheckout">

<value>false</value>

</property>

</bean>

以下是Hibernate 的配置dataSource的方式

<!-- Hibernate SessionFactory -->

<bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource">

<ref local="dataSource" />

</property>

<property name="mappingResources">

<list>

<value>com/xh/hibernate/vo/User.hbm.xml</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.generate_statistics">true</prop>

<prop key="hibernate.connection.release_mode">auto</prop>

<prop key="hibernate.autoReconnect">true</prop>

</props>

</property>

</bean>

</beans>

以下是ibatis的配置dataSource

<bean id="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:sqlmap-config.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

配置Spring數據源c3p0與dbcp

不管通過何種持久化技術,都必須通過數據連接訪問數據庫,在Spring中,數據連接是通過數據源獲得的。在以往的應用中,數據源一般是Web應用服務器提供的。在Spring中,你不但可以通過JNDI獲取應用服務器的數據源,也可以直接在Spring容器中配置數據源,此外,你還可以通過代碼的方式創建一個數據源,以便進行無依賴的單元測試

配置一個數據源

Spring在第三方依賴包中包含了兩個數據源的實現類包,其一是Apache的DBCP,其二是 C3P0。可以在Spring配置文件中利用這兩者中任何一個配置數據源。

DBCP數據源

DBCP類包位於 /lib/jakarta-commons/commons-dbcp.jar,DBCP是一個依賴 Jakarta commons-pool對象池機制的數據庫連接池,所以在類路徑下還必須包括/lib/jakarta- commons/commons-pool.jar。下面是使用DBCP配置MySql數據源的配置片斷:

xml 代碼

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close">

<property name="driverClassName" value="com.mysql.jdbc.Driver" />

<property name="url" value="jdbc:mysql://localhost:3309/sampledb" />

<property name="username" value="root" />

<property name="password" value="1234" />

</bean>

BasicDataSource提供了close()方法關閉數據源,所以必須設定destroy-method=”close”屬性, 以便Spring容器關閉時,數據源能夠正常關閉。除以上必須的數據源屬性外,還有一些常用的屬性:

defaultAutoCommit:設置從數據源中返回的連接是否採用自動提交機制,默認值爲 true;

defaultReadOnly:設置數據源是否僅能執行只讀操作, 默認值爲 false;

maxActive:最大連接數據庫連接數,設置爲0時,表示沒有限制;

maxIdle:最大等待連接中的數量,設置爲0時,表示沒有限制;

maxWait:最大等待秒數,單位爲毫秒, 超過時間會報出錯誤信息;

validationQuery:用於驗證連接是否成功的查詢SQL語句,SQL語句必須至少要返回一行數據, 如你可以簡單地設置爲:“select count(*) from user”;

removeAbandoned:是否自我中斷,默認是 false ;

removeAbandonedTimeout:幾秒後數據連接會自動斷開,在removeAbandoned爲true,提供該值;

logAbandoned:是否記錄中斷事件, 默認爲 false;

C3P0數據源

C3P0是一個開放源代碼的JDBC數據源實現項目,它在lib目錄中與Hibernate一起發佈,實現了JDBC3和JDBC2擴展規範說明的 Connection 和Statement 池。C3P0類包位於/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置一個 Oracle數據源:

xml 代碼

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"

destroy-method="close">

<property name="driverClass" value=" oracle.jdbc.driver.OracleDriver "/>

<property name="jdbcUrl" value=" jdbc:oracle:thin:@localhost:1521:ora9i "/>

<property name="user" value="admin"/>

<property name="password" value="1234"/>

</bean>

ComboPooledDataSource和BasicDataSource一樣提供了一個用於關閉數據源的close()方法,這樣我們就可以保證Spring容器關閉時數據源能夠成功釋放。

C3P0擁有比DBCP更豐富的配置屬性,通過這些屬性,可以對數據源進行各種有效的控制:

acquireIncrement:當連接池中的連接用完時,C3P0一次性創建新連接的數目;

acquireRetryAttempts:定義在從數據庫獲取新連接失敗後重復嘗試獲取的次數,默認爲30;

acquireRetryDelay:兩次連接中間隔時間,單位毫秒,默認爲1000;

autoCommitOnClose:連接關閉時默認將所有未提交的操作回滾。默認爲false;

automaticTestTable: C3P0將建一張名爲Test的空表,並使用其自帶的查詢語句進行測試。如果定義了這個參數,那麼屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操作,它將中爲C3P0測試所用,默認爲null;

breakAfterAcquireFailure:獲取連接失敗將會引起所有等待獲取連接的線程拋出異常。但是數據源仍有效保留,並在下次調 用getConnection()的時候繼續嘗試獲取連接。如果設爲true,那麼在嘗試獲取連接失敗後該數據源將申明已斷開並永久關閉。默認爲 false;

checkoutTimeout:當連接池用完時客戶端調用getConnection()後等待獲取新連接的時間,超時後將拋出SQLException,如設爲0則無限期等待。單位毫秒,默認爲0;

connectionTesterClassName:通過實現ConnectionTester或QueryConnectionTester的類來測試連接,類名需設置爲全限定名。默認爲 com.mchange.v2.C3P0.impl.DefaultConnectionTester;

idleConnectionTestPeriod:隔多少秒檢查所有連接池中的空閒連接,默認爲0表示不檢查;

initialPoolSize:初始化時創建的連接數,應在minPoolSize與maxPoolSize之間取值。默認爲3;

maxIdleTime:最大空閒時間,超過空閒時間的連接將被丟棄。爲0或負數則永不丟棄。默認爲0;

maxPoolSize:連接池中保留的最大連接數。默認爲15;

maxStatements:JDBC的標準參數,用以控制數據源內加載的PreparedStatement數量。但由於預緩存的Statement屬於單個Connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素,如果maxStatements與 maxStatementsPerConnection均爲0,則緩存被關閉。默認爲0;

maxStatementsPerConnection:連接池內單個連接所擁有的最大緩存Statement數。默認爲0;

numHelperThreads:C3P0是異步操作的,緩慢的JDBC操作通過幫助進程完成。擴展這些操作可以有效的提升性能,通過多線程實現多個操作同時被執行。默認爲3;

preferredTestQuery:定義所有連接測試都執行的測試語句。在使用連接測試的情況下這個參數能顯著提高測試速度。測試的表必須在初始數據源的時候就存在。默認爲null;

propertyCycle: 用戶修改系統配置參數執行前最多等待的秒數。默認爲300;

testConnectionOnCheckout:因性能消耗大請只在需要的時候使用它。如果設爲true那麼在每個connection提交的時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable

等方法來提升連接測試的性能。默認爲false;

testConnectionOnCheckin:如果設爲true那麼在取得連接的同時將校驗連接的有效性。默認爲false。

讀配置文件的方式引用屬性:

<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location" value="/WEB-INF/jdbc.properties"/>

</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close">

<property name="driverClassName" value="${jdbc.driverClassName}" />

<property name="url" value="${jdbc.url}" />

<property name="username" value="${jdbc.username}" />

<property name="password" value="${jdbc.password}" />


</bean>

在jdbc.properties屬性文件中定義屬性值:

jdbc.driverClassName= com.mysql.jdbc.Driver

jdbc.url= jdbc:mysql://localhost:3309/sampledb

jdbc.username=root

jdbc.password=1234

提示 經常有開發者在${xxx}的前後不小心鍵入一些空格,這些空格字符將和變量合併後作爲屬性的值。如: 的屬性配置項,在前後都有空格,被解析後,username的值爲“ 1234 ”,這將造成最終的錯誤,因此需要特別小心。

獲取JNDI數據源

如果應用配置在高性能的應用服務器(如WebLogic或Websphere等)上,我們可能更希望使用應用服務器本身提供的數據源。應用服務器的數據源使用JNDI開放調用者使用,Spring爲此專門提供引用JNDI資源的JndiObjectFactoryBean類。下面是一個簡單的配置:

xml 代碼

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName" value="java:comp/env/jdbc/bbt"/>

</bean>

通過jndiName指定引用的JNDI數據源名稱。

Spring 2.0爲獲取J2EE資源提供了一個jee命名空間,通過jee命名空間,可以有效地簡化J2EE資源的引用。下面是使用jee命名空間引用JNDI數據源的配置:

xml 代碼

<beans xmlns=http://www.springframework.org/schema/beans

xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance

xmlns:jee=http://www.springframework.org/schema/jee

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/jee

http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">

<jee:jndi-lookup id="dataSource" jndi-name=" java:comp/env/jdbc/bbt"/>

</beans>

Spring的數據源實現類

Spring本身也提供了一個簡單的數據源實現類DriverManagerDataSource ,它位於org.springframework.jdbc.datasource包中。這個類實現了javax.sql.DataSource接口,但它並沒有提供池化連接的機制,每次調用getConnection()獲取新連接時,只是簡單地創建一個新的連接。因此,這個數據源類比較適合在單元測試或簡單的獨立應用中使用,因爲它不需要額外的依賴類。

下面,我們來看一下DriverManagerDataSource的簡單使用:當然,我們也可以通過配置的方式直接使用DriverManagerDataSource。

java 代碼

DriverManagerDataSource ds = new DriverManagerDataSource ();

ds.setDriverClassName("com.mysql.jdbc.Driver");

ds.setUrl("jdbc:mysql://localhost:3309/sampledb");

ds.setUsername("root");

ds.setPassword("1234");

Connection actualCon = ds.getConnection();

小結

不管採用何種持久化技術,都需要定義數據源。Spring附帶了兩個數據源的實現類包,你可以自行選擇進行定義。在實際部署時,我們可能會直接採用應用服務器本身提供的數據源,這時,則可以通過JndiObjectFactoryBean或jee命名空間引用JNDI中的數據源。

DBCP與C3PO配置的區別:

C3PO :DBCP:

xml 代碼

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

<property name="driverClass">

<value>oracle.jdbc.driver.OracleDriver</value>

</property>

<property name="jdbcUrl">

<value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value>

</property>

<property name="user">

<value>testAdmin</value>

</property>

<property name="password">

<value>123456</value>

</property>

</bean>

xml 代碼

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName">

<value>oracle.jdbc.driver.OracleDriver</value>

</property>

<property name="url">

<value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value>

</property>

<property name="username">

<value>testAdmin</value>

</property>

<property name="password">

<value>123456</value>

</property>

</bean>

以下爲另一個參考:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://localhost:3306/mysql">
</property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>

如果改爲C3P0則爲:

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="autoCommitOnClose" value="true"/>
<property name="checkoutTimeout" value="${cpool.checkoutTimeout}"/>
<property name="initialPoolSize" value="${cpool.minPoolSize}"/>
<property name="minPoolSize" value="${cpool.minPoolSize}"/>
<property name="maxPoolSize" value="${cpool.maxPoolSize}"/>
<property name="maxIdleTime" value="${cpool.maxIdleTime}"/>
<property name="acquireIncrement" value="${cpool.acquireIncrement}"/>
<property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}"/>
</bean>
jdbc.properties:
# Database URL
jdbc.url=jdbc:mysql://192.168.0.25"3306/db
# Database login information
jdbc.username=root
jdbc.password=
# Time to wait for an open connection before timing out
# (in milliseconds)
cpool.checkoutTimeout=5000
# Connection pool size
cpool.minPoolSize=5
cpool.maxPoolSize=40
# How long to keep unused connections around(in seconds)
# Note: MySQL times out idle connections after 8 hours(28,800 seconds)
# so ensure this value is below MySQL idle timeout
cpool.maxIdleTime=25200
# How long to hang on to excess unused connections after traffic spike
# (in seconds)
cpool.maxIdleTimeExcessConnections=1800
# Acquiring new connections is slow, so eagerly retrieve extra connections
# when current pool size is reached
cpool.acquireIncrement=5

或者將上面的3部分寫成一個:
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass">
<value>${jdbc.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<property name="initialPoolSize"><value>10</value></property>
<property name="minPoolSize"><value>5</value></property>
<property name="maxPoolSize"><value>30</value></property>
<property name="acquireIncrement"><value>5</value></property>
<property name="maxIdleTime"><value>10</value></property>
<property name="maxStatements"><value>0</value></property>
</bean>

如果使用的是受管理的J2EE服務器,則在spring中配置爲JNDI連接:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jndi/xxx</value>
</property>
</bean>

如果在應用裏有獨自使用hibernate,則在spring中配置hibernate連接池,使用C3P0如下:
<bean id="DataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@172.16.20.241:1521:dbsvr</value>
</property>
<property name="username">
<value>hl3000</value>
</property>
<property name="password">
<value>hldw3101</value>
</property>
</bean>
<bean id="SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="DataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>

<!-- C3P0連接池配置 -->
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.timeout">120</prop>
<prop key="hibernate.c3p0.max_statements">100</prop>
<prop key="hibernate.c3p0.idle_test_period">120</prop>
<prop key="hibernate.c3p0.acquire_increment">2</prop>
<prop key="myeclipse.connection.profile">hl3000</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/hl3000/DBLogic/POJO/PermUserAccount.hbm.xml</value>
</list>
</property>
</bean>

spring中配置獨立使用hibernate時使用jndi的配置:

hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.datasource=java:comp/env/jdbc/SAMPLEDB
hibernate.show_sql=true

如果是使用不受管理的Servlet容器如Tomcat,也可以使用jndi的方式配置,需要在tomcat中配置數據源,在server.xml中增改大致如下:

<Resource name="jdbc/testDb" auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/testDB">\\數據源的名稱
<parameter><name>username</name><value>root</value></parameter>數據庫的名稱
<parameter><name>password</name><value>password</value></parameter>數據庫密碼
<parameter><name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value></parameter>\\要加載的驅動
<parameter><name>url</name>
<value>jdbc:mysql://172.20.0.73/rk?</value></parameter>\\要連接的URL
</ResourceParams>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章