欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI)

 更新時間:2018年10月31日 14:57:34   作者:deniro  
這篇文章主要介紹了淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

在 Spring 中,有以下三種方式來創(chuàng)建數(shù)據(jù)源:

  • 通過 JNDI 獲取應(yīng)用服務(wù)器中的數(shù)據(jù)源;
  • 在 Spring 容器中配置數(shù)據(jù)源;
  • 通過代碼來創(chuàng)建數(shù)據(jù)源,這種方式適用于無容器依賴的單元測試。

1 配置數(shù)據(jù)源

Spring 在第三方依賴包中包含了 2 種數(shù)據(jù)源的實現(xiàn)包 一個是 Apache 的 DBCP;另一個是 C3P0。 我們可以在 Spring 配置文件中直接配置這些數(shù)據(jù)源 。

1.1 DBCP

DBCP (Database Connection Pool)是一個依賴 Jakarta commons-pool 對象池機制的數(shù)據(jù)庫連接池,所以在類路徑下還必須包括 commons-pool.jar。 下面是使用 DBCP 配置 MySql 數(shù)據(jù)源的配置片段:

<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/db" />    
  <property name="username" value="root" />    
  <property name="password" value="xxxxxx" />    
</bean>  

BasicDataSource 提供了 close() 方法用于關(guān)閉數(shù)據(jù)源,所以必須設(shè)定 destroy-method=”close”, 以便 Spring 容器關(guān)閉時,能夠正常關(guān)閉數(shù)據(jù)源。

除以上必須的數(shù)據(jù)源屬性外,還有一些常用的屬性。

事務(wù)屬性:

屬性 默認值 說明
defaultAutoCommit true 連接默認為 auto-commit 狀態(tài)。
defaultReadOnly 驅(qū)動默認值 連接默認的 read-only 狀態(tài) 。如果沒有設(shè)置則 setReadOnly 方法將不會被調(diào)用。( 某些驅(qū)動不支持只讀模式 , 比如:Informix)
defaultTransactionIsolation 驅(qū)動默認值 連接默認的 TransactionIsolation 狀態(tài)。有這些值:NONE、READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ、SERIALIZABLE。

連接數(shù)相關(guān)屬性:

屬性 默認值 說明
initialSize 0 初始化連接數(shù):連接池啟動時創(chuàng)建的初始化連接數(shù)量。
maxActive 8 最大活動連接 : 連接池在同一時間內(nèi)能夠分配的最大活動連接的數(shù)量。如果設(shè)置為非正數(shù),則表示不限制。
maxIdle 8 最大空閑連接 : 連接池中容許保持空閑狀態(tài)的最大連接數(shù)量 , 超過的空閑連接將被釋放 , 如果設(shè)置為負數(shù),則表示不限制。
minIdle 0 最小空閑連接 : 連接池中容許保持空閑狀態(tài)的最小連接數(shù)量 , 低于這個數(shù)量將創(chuàng)建新的連接 , 如果設(shè)置為 0,則表示不創(chuàng)建。
maxWait 無限 最大等待時間 : 當(dāng)沒有可用連接時 , 連接池等待連接被歸還的最大時間 ( 單位為毫秒 ) , 超出時間將拋出異常 , 如果設(shè)置為 -1,則表示無限等待。

連接監(jiān)測與維護相關(guān)屬性:

屬性 默認值 說明
validationQuery 配置 SQL 查詢語句 , 用于驗證從連接池取出的連接是否可用。如果指定 , 則查詢必須是一個 SQL SELECT,并且必須返回至少一行記錄。MySQL 中是 “select 1”;在 Oracle 中是 "select 1 from dual"。
testOnBorrow true 指明是否從連接池中取出連接之前進行檢測 , 如果檢測失敗 , 則從池中去除連接并嘗試取出另一個新的連接。 注意 : 設(shè)置為 true 后如果要生效,則 validationQuery 參數(shù)必須正確被設(shè)置。
testOnReturn false 指明是否在歸還到池中前進行檢測。 注意 : 與 testOnBorrow 一樣,設(shè)置為 true 后如果要生效,則 validationQuery 參數(shù)必須正確被設(shè)置。
testWhileIdle false 指明連接是否會被空閑連接回收器 ( 如果有 ) 所檢測。 如果檢測失敗 , 則連接將從池中被移除。 注意 : 設(shè)置為 true 后如果要生效,則 validationQuery 參數(shù)必須正確被設(shè)置。
timeBetweenEvictionRunsMillis -1 空閑連接回收器線程運行的周期 , 以毫秒為單位。如果設(shè)置為非正數(shù) , 則不運行空閑連接回收器線程。 注意 : 啟用該參數(shù)時,則 validationQuery 參數(shù)必須正確被設(shè)置。
numTestsPerEvictionRun 3 在每次空閑連接回收器線程 ( 如果有 ) 運行時需要檢測的連接數(shù)量。
minEvictableIdleTimeMillis 1000 * 60 * 30 連接在池中保持空閑而不被空閑連接回收器線程回收的最小時間值,以毫秒為單位。

緩存相關(guān)屬性:

屬性 默認值 說明
poolPreparedStatements false 開啟連接池的 prepared statement 功能設(shè)置為 true 后,所有的 CallableStatement 和 PreparedStatement 都會被緩存起來。
maxOpenPreparedStatements 不限制 能夠同時分配打開的 statements 的最大數(shù)量。0 表示不限制。

連接泄露回收相關(guān)屬性:

屬性 默認值 說明
removeAbandoned false 是否刪除泄露的連接。如果設(shè)置為 true, 那么那些可能存在泄露的連接會被刪除。假設(shè) maxActive 為 10 個,活動連接為 8 個,空閑連接為 1 個,10-8-1=1,那么就會把刪除這個連接(會先檢測該活動連接未被使用的時間是否超過 removeAbandonedTimeout)。如果需要一個長連接操作,那么 removeAbandoned 需要設(shè)置的長一些,否則正常使用的連接可能會被誤刪除。
removeAbandonedTimeout 300 泄露的連接可以被刪除的時間段,單位為秒。
logAbandoned false 當(dāng) Statement 或連接被泄露時是否打印堆棧日志 。

假設(shè)數(shù)據(jù)庫用的是 MySQL,那么如果數(shù)據(jù)源配置不當(dāng),將可能會發(fā)生經(jīng)典的 “8 小時問題 ”。 原因是 MySQL 在默認情況下如果發(fā)現(xiàn)一個連接的空閑時間超過 8 小時,那么會在數(shù)據(jù)庫端自動關(guān)閉這個連接 。 而數(shù)據(jù)源并不知道這個連接已經(jīng)被關(guān)閉了,所以當(dāng)它將這個無用的連接返回給某個 DAO 時, DAO 就會拋出無法獲取 connection 的異常 。

DBCP 的 testOnBorrow 默認設(shè)置為 true,所以從連接池中取出連接之前會先進行檢測,因為不會發(fā)生 “8 小時問題 ”。 但如果每次取連接時都進行檢測,那么在高并發(fā)應(yīng)用下就會產(chǎn)生性能問題。

因此建議在高并發(fā)下,將 testOnBorrow 設(shè)置為 false;然后將 testWhileIdle 設(shè)置為 true,打開空閑連接回收器;最后把 timeBetweenEvictionRunsMillis 的值設(shè)定為小于 8 小時,這樣那些被 MySQL 所關(guān)閉的空閑連接,就會被清除出去。這樣不僅解決了 “8 小時問題 ”,而且還保證了高性能 O(∩_∩)O哈哈~

注意:因為 MySQL 本身的 interactive-timeout(單位為 s)參數(shù),可以設(shè)定空閑連接的過期時間,所以我們要想獲取到這個參數(shù)值,然后再設(shè)定 DBCP 的 timeBetweenEvictionRunsMillis 屬性值。

1.2 C3P0

C3P0 是一個開放源代碼的 JDBC 數(shù)據(jù)源實現(xiàn)項目,它實現(xiàn)了 JDBC3 和 JDBC2 擴展規(guī)范說明的 Connection 和 Statement 池。

下面是使用 C3P0 配置 MySql 數(shù)據(jù)源的配置片段:

<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:mysql://localhost:3309/db" />    
  <property name="use" value="xxx" />    
  <property name="password" value="xxxxxx" />    
</bean>  


C3P0 也提供了一個用于關(guān)閉數(shù)據(jù)源的 close() 方法,這樣我們就可以保證 Spring 容器被關(guān)閉時,能夠成功關(guān)閉數(shù)據(jù)源 。

屬性 默認值 說明
acquireIncrement 當(dāng)連接池中無空閑連接時, 一次性創(chuàng)建新連接的數(shù)量。
acquireRetryAttempts 30 在從數(shù)據(jù)庫獲取新連接失敗后,重復(fù)嘗試的次數(shù)。
acquireRetryDelay 1000 嘗試獲取連接之間的間隔時間,單位為毫秒。
autoCommitOnClose false 連接關(guān)閉時,將所有未提交的操作回滾 。
automaticTestTable null 會創(chuàng)建一張名為 Test 的空表,并使用其自帶的查詢語句進行測試 。 如果定義了這個參數(shù),那么 preferredTestQuery 屬性 將被忽略 。 我們不能在這張 Test 表上進行任何操作,它僅為 C3P0 測試所用。
breakAfterAcquireFailure false 獲取連接失敗時,將會引起所有等待獲取連接的線程拋出異常 。 但是數(shù)據(jù)源仍有效保留,并在下次調(diào)用 getConnection() 時繼續(xù)嘗試獲取連接 。 在嘗試獲取連接失敗后,該數(shù)據(jù)源將申明已斷開并永久關(guān)閉。
checkoutTimeout 0 當(dāng)連接池中的連接用完時,客戶端調(diào)用 getConnection() 后等待獲取新連接的時間,單位:毫秒。超時后將拋出 SQLException 。設(shè)為 0 表示無限期等待 。
connectionTesterClassName com.mchange.v2.C3P0.impl.DefaultConnectionTester 通過實現(xiàn) ConnectionTester 或 QueryConnectionTester 的類來測試連接,類名需設(shè)置為全限定名 。
idleConnectionTestPeriod 0 隔多少秒,檢查連接池中的所有空閑連接。0 表示不檢查。
initialPoolSize 3 初始化時創(chuàng)建的連接數(shù),應(yīng)在 minPoolSize 與 maxPoolSize 之間取值 。
maxIdleTime 0 最大空閑時間,超過空閑時間的連接將會被丟棄 。 為 0 或負數(shù)則表示永不丟棄 。
maxPoolSize 15 連接池中保留的最大連接數(shù) 。
maxStatements 0 JDBC 標準參數(shù),用以控制數(shù)據(jù)源內(nèi)加載的 PreparedStatement 數(shù)量 。 但由于預(yù)緩存的 Statement 屬于單個 Connection 而不是整個連接池 。 所以設(shè)置這個參數(shù)需要多方面的考慮,如果 maxStatements 與 maxStatementsPerConnection 均為 0 ,則緩存被關(guān)閉 。
maxStatementsPerConnection 0 連接池內(nèi)單個連接所擁有的最大緩存 Statement 數(shù) 。
numHelperThreads 3 C3P0 是異步操作的,緩慢的 JDBC 操作通過 HelperThreads 完成 。 通過多線程實現(xiàn)多個操作同時被執(zhí)行,這樣可以有效地提升性能。
preferredTestQuery null 定義所有連接測試都執(zhí)行的測試語句。在使用連接測試的情況下,這個參數(shù)能夠顯著地提高測試速度。測試的表必須在初始數(shù)據(jù)源時就存在。
propertyCycle 300 修改系統(tǒng)配置參數(shù)生效時長,單位為 s。
testConnectionOnCheckout false 因性能消耗大,所以請只在需要時開啟 。 如果設(shè)為 true 那么在每個 connection 提交的時候都將校驗其有效性 。 建議使用 idleConnectionTestPeriod 或 automaticTestTable 等方法來提升連接測試的性能 。
testConnectionOnCheckin false 如果設(shè)為 true,那么在取得連接的同時將校驗其連接的有效性。

2 JNDI 數(shù)據(jù)源

如果應(yīng)用配置在高性能的應(yīng)用服務(wù)器(如 WebLogic 或 Websphere 等)上,我們可能更希望使用應(yīng)用服務(wù)器所提供的數(shù)據(jù)源 。 應(yīng)用服務(wù)器的數(shù)據(jù)源使用 JNDI 方式來供調(diào)用者使用, Spring 為此專門提供了引用 JNDI 資源的 JndiObjectFactoryBean 類 。 下面是一個簡單的配置:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
   p:jndiName="java:comp/env/jdbc/ds"/>

Spring2.0+ 為獲取 J2EE 資源提供了一個 jee 命名空間,通過 jee 命名空間,可以有效地簡化 J2EE 資源的引用:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
   http://www.springframework.org/schema/jee
   http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
   ">

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

</beans>

3 Spring 數(shù)據(jù)源實現(xiàn)類

Spring 本身也提供了一個簡單的數(shù)據(jù)源實現(xiàn)類 DriverManagerDataSource ,它位于 org.springframework.jdbc.datasource 包中 。 這個類實現(xiàn)了 javax.sql.DataSource 接口,但它并沒有提供池化連接機制,每次調(diào)用 getConnection() 方法獲取新連接時,只是簡單地創(chuàng)建一個新的連接 。它不需要額外的依賴類,所以,這個數(shù)據(jù)源類比較適合在單元測試中使用 。

Spring 數(shù)據(jù)源實現(xiàn)類既可以通過配置直接使用,也可以在代碼中實例化調(diào)用:

DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/spring4");
dataSource.setUsername("root");
dataSource.setPassword("");

try {
  Connection connection=dataSource.getConnection();
  if(connection.isClosed()){
    System.out.println("連接已關(guān)閉");
  }else{
    System.out.println("連接已開啟");
  }
} catch (SQLException e) {
  e.printStackTrace();
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring-cloud入門之eureka-client(服務(wù)注冊)

    spring-cloud入門之eureka-client(服務(wù)注冊)

    本篇文章主要介紹了spring-cloud入門之eureka-client(服務(wù)注冊),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 如何在 Java 中實現(xiàn)不可變類

    如何在 Java 中實現(xiàn)不可變類

    這篇文章主要介紹了如何在 Java 中實現(xiàn)不可變類,不變性是函數(shù)式編程的關(guān)鍵,因為它與盡量減少變化部分的這一目標相一致,這使得對這些部分的推斷更為容易一些。,需要的朋友可以參考下
    2019-06-06
  • 最新評論