連接池的使用場景


本文分為四部分

  • 純java數據庫連接池的使用
  • 數據源DataSource的連接信息
  • spring集成的DataSource
  • spring boot集成的DataSource

1、連接池概述

> 數據庫連接是一種關鍵的有限的昂貴的資源,這一點在多用戶的網頁應用程序中體現得尤為突出。對數據庫連接的管理能顯著影響到整

個應用程序的伸縮性和健壯性,影響到程序的性能指標。數據庫連接池正是針對這個問題提出來的。
  數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而再不是重新建立一個;釋放空閑時
間超過最大空閑時間的數據庫連接來避免因為沒有釋放數據庫連接而引起的數據庫連接遺漏。這項技術能明顯提高對數據庫操作的性能。
  數據庫連接池在初始化時將創建一定數量的數據庫連接放到連接池中,這些數據庫連接的數量是由最小數據庫連接數來設定的。無論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量。連接池的最大數據庫連接數量限定了這個連接池能占有的最大連接數,當應用程序向連接池請求的連接數超過最大連接數量時,這些請求將被加入到等待隊列中。數據庫連接池的最小連接數和最大連接數的設置要考慮到下列幾個因素:
  1) 最小連接數是連接池一直保持的數據庫連接,所以如果應用程序對數據庫連接的使用量不大,將會有大量的數據庫連接資源被浪費;
  2) 最大連接數是連接池能申請的最大連接數,如果數據庫連接請求超過此數,后面的數據庫連接請求將被加入到等待隊列中,這會影響之后的數據庫操作。
  3) 如果最小連接數與最大連接數相差太大,那么最先的連接請求將會獲利,之后超過最小連接數量的連接請求等價於建立一個新的數據庫連接。不過,這些大於最小連接數的數據庫連接在使用完不會馬上被釋放,它將被放到連接池中等待重復使用或是空閑超時后被釋放。
  目前常用的連接池有:C3P0、DBCP、Proxool

  • C3P0比較耗費資源,效率方面可能要低一點。
  • DBCP在實踐中存在BUG,在某些種qi會產生很多空連接不能釋放,Hibernate3.0已經放棄了對其的支持。
  • Proxool的負面評價較少,現在比較推薦它,而且它還提供即時監控連接池狀態的功能,便於發現連接泄漏的情況。

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

Java數據庫連接池其特點

  • 主流的數據庫連接池
    在目前技術前沿比較流行的數據庫連接池有:DBCP、Tomcat Jdbc Pool、BoneCP、Druid、C3P0等
  • DBCP:由Apache開發的一個Java數據庫連接池項目, Jakarta commons-pool對象池機制,Tomcat使用的連接池組件就是DBCP。單獨使用dbcp需要3個包:common-dbcp.jar,common-pool.jar,common-collections.jar,預先將數據庫連接放在內存中,應用程序需要建立數據庫連接時直接到連接池中申請一個就行,用完再放回。單線程,並發量低,性能不好,適用於小型系統。
  • Tomcat Jdbc Pool:Tomcat在7.0以前都是使用common-dbcp做為連接池組件,但是dbcp是單線程,為保證線程安全會鎖整個連接池,性能較差,dbcp有超過60個類,也相對復雜。Tomcat從7.0開始引入了新增連接池模塊叫做Tomcat jdbc pool,基於Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通過異步方式獲取連接,支持高並發應用環境,超級簡單核心文件只有8個,支持JMX,支持XA Connection。
  • BoneCP:官方說法BoneCP是一個高效、免費、開源的Java數據庫連接池實現庫。設計初衷就是為了提高數據庫連接池性能,根據某些測試數據顯示,BoneCP的速度是最快的,要比當時第二快速的連接池快25倍左右,完美集成到一些持久化產品如Hibernate和DataNucleus中。BoneCP特色:高度可擴展,快速;連接狀態切換的回調機制;允許直接訪問連接;自動化重置能力;JMX支持;懶加載能力;支持XML和屬性文件配置方式;較好的Java代碼組織,100%單元測試分支代碼覆蓋率;代碼40KB左右。
  • Druid:Druid是Java語言中最好的數據庫連接池,Druid能夠提供強大的監控和擴展功能,是一個可用於大數據實時查詢和分析的高容錯、高性能的開源分布式系統,尤其是當發生代碼部署、機器故障以及其他產品系統遇到宕機等情況時,Druid仍能夠保持100%正常運行。主要特色:為分析監控設計;快速的交互式查詢;高可用;可擴展;Druid是一個開源項目,源碼托管在github上。
  • C3p0:開源的JDBC連接池,實現了數據源和JNDI綁定,支持JDBC3規范和JDBC2的標准擴展。目前使用它的開源項目有Hibernate、Spring等。單線程,性能較差,適用於小型系統,代碼600KB左右。
  • 他們之間的對比
    他們之間的對比圖
  • 再看一組有HikariCP的
    與HikariCP的比較
  • HikariCP性能分析
    1.HikariCP通過優化(concurrentBag,fastStatementList )集合來提高並發的讀寫效率。
    2.HikariCP使用threadlocal緩存連接及大量使用CAS的機制,最大限度的避免lock。單可能帶來cpu使用率的上升。
    3.從字節碼的維度優化代碼。 (default inline threshold for a JVM running the server Hotspot compiler is 35 bytecodes )讓方法盡量在35個字節碼一下,來提升jvm的處理效率。
  • 比HikariCP更快的數據庫連接池:
    一個同事告訴我,比hikari還快的連接池他也用過、研究過 https://github.com/mauricio/postgresql-async 這是scala生態圈的東西。用netty實現了mysql協議,沒用mysql官方的connector,純異步的,它的連接池是寫的比較隨便,但是性能依然很好。
  • 從Sharding-jdbc架構演進看未來:
    Database Mesh,一個搭乘 Service Mesh 浪潮衍生出來的新興詞匯。顧名思義,Database Mesh 使用一個嚙合層,將散落在系統各個角落中的數據庫統一治理起來。通過嚙合層集中在一起的應用與數據庫之間的交互網絡,就像蜘蛛網一樣復雜而有序。它的首要目標並非嚙合存儲於數據庫中的數據,而是嚙合應用與數據庫間的交互。

2.純java連接數據庫

dbcp連接池

封裝dbcp連接池創建一個數據庫工具類

/**
*(封裝dbcp連接池來創建數據庫工具類)
*(屬性文件為源文件夾properties下的dbcpconfig.properties)
*/
public class DatabaseUtil {

/**
 * 數據庫連接池(dbcp連接池)對象引用
   */
   private static DataSource dbcpPoor;

/**
 * 只執行一次
   */
   static {
   Properties properties = new Properties();
   ClassLoader classLoader = DatabaseUtil.class.getClassLoader();
   InputStream resourceAsStream = classLoader.getResourceAsStream(“dbcpconfig.properties”);
   try {
       properties.load(resourceAsStream);
       //通過直接創建連接池對象並設置參數方法創建連接池對象
   //          BasicDataSource basicDataSource = new BasicDataSource();
   //          basicDataSource.setUsername(properties.getProperty(“username”));
   //          basicDataSource.setPassword(properties.getProperty(“password”));
   //          basicDataSource.setDriverClassName(properties.getProperty(“driverClassName”));
   //          basicDataSource.setUrl(properties.getProperty(“url”));
   //          
   //          dbcpPoor = basicDataSource;
       //通過工廠的方法創建連接池對象
       dbcpPoor = BasicDataSourceFactory.createDataSource(properties);
   } catch (Exception e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
   }
   }
    
    /**

 * 獲取連接對象
 * @throws SQLException 
   */
   public static Connection getConnection() throws SQLException{
   Connection connection = dbcpPoor.getConnection();
   System.out.println(“獲取連接對象成功”);
   return connection;
   }

/**

 * 關閉資源
   */
   //關閉建立的連接對象,釋放資源
   public static void closeSourceConnection(Connection connection, Statement statement, ResultSet resultSet){

       try {
           if (connection!=null) {
               connection.close();
           }
           if (statement!=null) {
               statement.close();
           }
           if (resultSet!=null) {
               resultSet.close();
           }
       } catch (SQLException e) {
           e.printStackTrace();
       }

   }

   public static DataSource getDbcpPoor() {
   return dbcpPoor;
   }
   }

c3p0連接池

封裝c3p0連接池創建一個數據庫工具類

/**

 * (封裝c3p0連接池來創建數據庫工具類)

 * @author YanoHao
   *
    */
   public class DatabaseUtil {
   /**

    * c3p0連接池對象的引用
      */
      private static DataSource c3p0Poor;
      /**

    * 創建一次
      */
      static {
      //直接創建連接池對象(自動加載配置文件,無需設置參數)
      c3p0Poor = new ComboPooledDataSource();
      //通過工廠的方式創建連接池對象
      //      try {
      //          DataSource unpooledDataSource = DataSources.unpooledDataSource();
      //          c3p0Poor = DataSources.pooledDataSource(unpooledDataSource);
      //      } catch (SQLException e) {
      //          // TODO Auto-generated catch block
      //          e.printStackTrace();
      //      }
      }
      /**

    * 獲取連接對象

    * @throws SQLException 
      */
      public static Connection getConnection() throws SQLException{

      Connection connection = c3p0Poor.getConnection();
      System.out.println(“獲取連接對象成功”);
      return connection;
      }

   /**

    * 關閉資源
      */
      //關閉建立的連接對象,釋放資源
      public static void closeSourceConnection(Connection connection, Statement statement, ResultSet resultSet){

          try {
              if (connection!=null) {
                  connection.close();
              }
              if (statement!=null) {
                  statement.close();
              }
              if (resultSet!=null) {
                  resultSet.close();
              }
          } catch (SQLException e) {
              e.printStackTrace();
          }

      }

      public static DataSource getC3p0Poor() {
          return c3p0Poor;
      }
      }

druid連接池

封裝druid連接池創建一個數據庫工具類

/*

 * 封裝druid連接池創建工具類
   */
   public class DatabaseUtil {

   /**

    * 數據庫連接池(druid連接池)對象引用
      */
      private static DataSource druidPool;

   static {
       try {
           Properties properties = new Properties();
           ClassLoader classLoader = DatabaseUtil.class.getClassLoader();
           InputStream resourceAsStream = classLoader.getResourceAsStream(“druidconfig.properties”);
           properties.load(resourceAsStream);
           //通過直接創建連接池對象的方式創建連接池對象
   //          DruidDataSource druidDataSource = new DruidDataSource();
   //          druidDataSource.setUsername(properties.getProperty(“username”));
   //          druidDataSource.setPassword(properties.getProperty(“password”));
   //          druidDataSource.setUrl(properties.getProperty(“url”));
   //          druidDataSource.setDriverClassName(properties.getProperty(“driverClassName”));
   //          druidPool = druidDataSource;
           //通過工廠的方式創建連接池對象
           druidPool = DruidDataSourceFactory.createDataSource(properties);
       } catch (Exception e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }   
   }

   public static Connection getConnection() throws SQLException{

       Connection connection = druidPool.getConnection();
       return connection;

   }

   /**

    * 

    * 關閉建立的連接對象,釋放資源
      */
      public static void closeSourceConnection(Connection connection, Statement statement, ResultSet resultSet){

      try {
          if (connection!=null) {
              connection.close();
          }
          if (statement!=null) {
              statement.close();
          }
          if (resultSet!=null) {
              resultSet.close();
          }
      } catch (SQLException e) {
          e.printStackTrace();
      }
      }

   public static DataSource getDruidPool() {
       return druidPool;
   }
   }

3.spring集成連接池

1、DBCP數據源

  DBCP類包為commons-dbcp.jar,DBCP是一個依賴 Jakarta commons-pool對象池機制的數據庫連接池,所以還應包含commons-pool.jar。

bean配置片段:

<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:3306/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;

2、C3P0數據源

C3P0是一個開放源代碼的JDBC數據源實現項目,它在lib目錄中與Hibernate一起發布,實現了JDBC3和JDBC2擴展規范說明的 Connection 和Statement 池。C3P0類包為c3p0-0.9.0.4.jar。

bean配置片段:


<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"        
        destroy-method="close">       
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>       
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/sampledb"/>       
    <property name="user" value="root"/>       
    <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。

3、Proxool數據源

  sourceforge下的一個開源項目,這個項目提供一個健壯、易用的連接池,最為關鍵的是這個連接池提供監控的功能,方便易用,便於發現連接泄漏的情況。

可在官網http://proxool.sourceforge.net下載需要的jar包。

<bean id="dataSource"
    class="org.logicalcobwebs.proxool.ProxoolDataSource">
    <property name="driver">
        <value>com.mysql.jdbc.Driver</value>
    </property>
    <property name="driverUrl">
        <value>jdbc:mysql://localhost:3306/sampledb?user=root&password=1234</value>
    </property>
    <property name="user" value="yourname" />
    <property name="password" value="yourpass" />
    <property name="alias" value="Pool_dbname" />
    <property name="houseKeepingSleepTime" value="90000" />
    <property name="prototypeCount" value="0" />
    <property name="maximumConnectionCount" value="50" />
    <property name="minimumConnectionCount" value="2" />
    <property name="simultaneousBuildThrottle" value="50" />
    <property name="maximumConnectionLifetime" value="14400000" />
    <property name="houseKeepingTestSql" value="select CURRENT_DATE" />
</bean>

這種方式需要把用戶名和密碼寫在連接串里面,ProxoolDataSource類提供的user,password屬性似乎沒有什么用。無論提供什么,它都會以空用戶名、密碼去連接數據庫,但是user,password兩個屬性必須設置,否則hibernate會報空指針錯誤。

常用配置:

   fatal-sql-exception: 它是一個逗號分割的信息片段.當一個SQL異常發生時,他的異常信息將與這個信息片段進行比較.如果在片段中存在,那么這個異常將被認為是個致命錯誤 
(Fatal SQL Exception ).這種情況下,數據庫連接將要被放棄.無論發生什么,這個異常將會被重擲以提供給消費者.用戶最好自己配置一個不同的異常來拋出.
  fatal-sql-exception-wrapper-class:正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,用戶可以包裝
  SQLException,使他變成另外一個異常.這個異常或者繼承SQLException或者繼承字RuntimeException.proxool
自帶了2個實現:'org.logicalcobwebs.proxool.FatalSQLException' 和'org.logicalcobwebs.proxool.FatalRuntimeException'.后者更合適.
  house-keeping-sleep-time: house keeper 保留線程處於睡眠狀態的最長時間,house keeper 的職責就是檢查各個連接的狀態,並判斷是否需要銷毀或者創建.
  house-keeping-test-sql: 如果發現了空閑的數據庫連接.house keeper 將會用這個語句來測試.這個語句最好非常快的被執行.如果沒有定義,測試過程將會被忽略。
  injectable-connection-interface: 允許proxool實現被代理的connection對象的方法.
  injectable-statement-interface: 允許proxool實現被代理的Statement 對象方法.
  injectable-prepared-statement-interface: 允許proxool實現被代理的PreparedStatement 對象方法.
  injectable-callable-statement-interface: 允許proxool實現被代理的CallableStatement 對象方法.
  jmx: 如果屬性為true,就會注冊一個消息Bean到jms服務,消息Bean對象名: "Proxool:type=Pool, name=<alias>". 默認值為false.
  jmx-agent-id: 一個逗號分隔的JMX代理列表(如使用MBeanServerFactory.findMBeanServer(String agentId)注冊的連接池。)這個屬性是僅當"jmx"屬性設置為"true"才有效。
所有注冊jmx服務器使用這個屬性是不確定的
  jndi-name: 數據源的名稱
  maximum-active-time: 如果housekeeper 檢測到某個線程的活動時間大於這個數值.它將會殺掉這個線程.
所以確認一下你的服務器的帶寬.然后定一個合適的值.默認是5分鍾.
  maximum-connection-count: 最大的數據庫連接數.
  maximum-connection-lifetime: 一個線程的最大壽命.
  minimum-connection-count: 最小的數據庫連接數
  overload-without-refusal-lifetime: 這可以幫助我們確定連接池的狀態。如果我們已經拒絕了一個連接在這個設定值(毫秒),然后被認為是超載。默認為60秒。
  prototype-count: 連接池中可用的連接數量.如果當前的連接池中的連接少於這個數值.新的連接將被建立(假設沒有超過最大可用數).例如.我們有3個活動連接2個可用連接,
而我們的prototype-count是4,那么數據庫連接池將試圖建立另外2個連接.這和 minimum-connection-count不同. minimum-connection-count
把活動的連接也計算在內.prototype-count 是spare connections 的數量.
  recently-started-threshold: 這可以幫助我們確定連接池的狀態,連接數少還是多或超載。只要至少有一個連接已開始在此值(毫秒)內,或者有一些多余的可用連接,
那么我們假設連接池是開啟的。默認為60秒
  simultaneous-build-throttle: 這是我們可一次建立的最大連接數。那就是新增的連接請求,但還沒有可供使用的連接。由於連接可以使用多線程,
在有限的時間之間建立聯系從而帶來可用連接,但是我們需要通過一些方式確認一些線程並不是立即響應連接請求的,默認是10。
  statistics: 連接池使用狀況統計。參數“10s,1m,1d”
  statistics-log-level: 日志統計跟蹤類型。參數“ERROR”或 “INFO”
  test-before-use: 如果為true,在每個連接被測試前都會服務這個連接,如果一個連接失敗,那么將被丟棄,另一個連接將會被處理,如果所有連接都失敗,
一個新的連接將會被建立。否則將會拋出一個SQLException異常。
  test-after-use: 如果為true,在每個連接被測試后都會服務這個連接,使其回到連接池中,如果連接失敗,那么將被廢棄。
  trace: 如果為true,那么每個被執行的SQL語句將會在執行期被log記錄(DEBUG LEVEL).你也可以注冊一個ConnectionListener (參看ProxoolFacade)得到這些信息.

4、獲取JNDI數據源

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

一個簡單的配置片段:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">       
    <property name="jndiName" value="java:comp/env/jdbc/sample"/>       
</bean>

使用jee命名空間引用JNDI數據源的配置片段:

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


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:jee=http://www.springframework.org/schema/jee 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
      
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/sample"/>
  
</beans>

5、Spring的數據源實現類

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

DriverManagerDataSource ds = new DriverManagerDataSource ();       
ds.setDriverClassName("com.mysql.jdbc.Driver");       
ds.setUrl("jdbc:mysql://localhost:3306/sampledb");       
ds.setUsername("root");       
ds.setPassword("1234");       
Connection actualCon = ds.getConnection();

6.druid連接池的使用

1. Druid的簡介

  Druid是一個數據庫連接池。Druid是目前最好的數據庫連接池,在功能、性能、擴展性方面,都超過其他數據庫連接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已經在阿里巴巴部署了超過600個應用,經過一年多生產環境大規模部署的嚴苛考驗。Druid是阿里巴巴開發的號稱為監控而生的數據庫連接池。

2. Druid組成

•Druid是一個JDBC組件,它包括三部分:

  •1、DruidDriver 代理Driver,能夠提供基於Filter-Chain模式的插件體系。可以監控數據庫訪問性能

  •2、DruidDataSource 高效可管理的數據庫連接池,充當數據庫連接池

  •3、SQLParser ,獲得SQL執行日志

3. Druid功能

  •1) 可以監控數據庫訪問性能,Druid內置提供了一個功能強大的StatFilter插件,能夠詳細統計SQL的執行性能,這對於線上分析數據庫訪問性能有幫助。

  •2) 替換DBCP和C3P0。Druid提供了一個高效、功能強大、可擴展性好的數據庫連接池。

  •3) 數據庫密碼加密。直接把數據庫密碼寫在配置文件中,這是不好的行為,容易導致安全問題。DruidDruiver和DruidDataSource都支持PasswordCallback。

  •4) SQL執行日志,Druid提供了不同的LogFilter,能夠支持Common-Logging、Log4j和JdkLog,你可以按需要選擇相應的LogFilter,監控你應用的數據庫訪問情況。

  •5)擴展JDBC,如果你要對JDBC層有編程的需求,可以通過Druid提供的Filter-Chain機制,很方便編寫JDBC層的擴展插件。

<!--數據庫連接池配置 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        destroy-method="close" lazy-init="false">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="1" />
        <property name="maxActive" value="50" />
        <property name="maxWait" value="30000" />
 
        <property name="filters" value="stat,wall" />
        <property name="timeBetweenEvictionRunsMillis" value="3000" />
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <property name="validationQuery" value="SELECT 'x'" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize"
            value="20" />
    </bean>    

7.HiKariCP連接池

pom.xml依賴


<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>2.4.7</version>
</dependency>

datacourse

<bean id = "dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maximumPoolSize" value="100" />
		<property name="minimumIdle" value="10" />
		<property name="connectionTestQuery" value="select 1" />
		<property name="dataSourceProperties">
			<props>
				<prop key="cachePrepStmts">true</prop>
				<prop key="prepStmtCacheSize">250</prop>
				<prop key="prepStmtCacheSqlLimit">2048</prop>
				<prop key="useServerPrepStmts">true</prop>
			</props>
		</property>
	</bean>

4.spring boot使用的連接池

1.Hikaricp

springboot 2.0 默認連接池就是Hikari了,所以引用parents后不用專門加依賴;
application.yml中添加以下配置即可:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: mone_rootadfadsf
    password: nYWTpo1Tr7CfiWKtafadsf
    url: jdbc:mysql://rm-bp194e4uj9873e6m6lo.mysql.rds.aliyunafscs.com:3306/mone_tsdfest?characterEncoding=utf-8&useSSL=false
    hikari:
      # 連接只讀數據庫時配置為true, 保證安全
      read-only: true
      # 等待連接池分配連接的最大時長(毫秒),超過這個時長還沒可用的連接則發生SQLException, 缺省:30秒
      connection-timeout: 30000
      # 一個連接idle狀態的最大時長(毫秒),超時則被釋放(retired),缺省:10分鍾
      idle-timeout: 600000
      # 一個連接的生命時長(毫秒),超時而且沒被使用則被釋放(retired),缺省:30分鍾,建議設置比數據庫超時時長少30秒
      max-lifetime: 1800000
      # 連接池中允許的最大連接數。缺省值:10
      maximum-pool-size: 60
      minimum-idle: 10

2.Druid

Druid的簡介

Druid首先是一個數據庫連接池。Druid是目前最好的數據庫連接池,在功能、性能、擴展性方面,都超過其他數據庫連接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已經在阿里巴巴部署了超過600個應用,經過一年多生產環境大規模部署的嚴苛考驗。Druid是阿里巴巴開發的號稱為監控而生的數據庫連接池!

同時Druid不僅僅是一個數據庫連接池,它包括四個部分:

Druid是一個JDBC組件.

基於Filter-Chain模式的插件體系.

DruidDataSource 高效可管理的數據庫連接池.

SQLParser.

Druid的功能:

1、替換DBCP和C3P0。Druid提供了一個高效、功能強大、可擴展性好的數據庫連接池。

2、可以監控數據庫訪問性能,Druid內置提供了一個功能強大的StatFilter插件,能夠詳細統計SQL的執行性能,這對於線上分析數據庫訪問性能有幫助。

3、數據庫密碼加密。直接把數據庫密碼寫在配置文件中,這是不好的行為,容易導致安全問題。DruidDruiver和DruidDataSource都支持PasswordCallback。

4、SQL執行日志,Druid提供了不同的LogFilter,能夠支持Common-Logging、Log4j和JdkLog,你可以按需要選擇相應的LogFilter,監控你應用的數據庫訪問情況。

5、擴展JDBC,如果你要對JDBC層有編程的需求,可以通過Druid提供的Filter機制,很方便編寫JDBC層的擴展插件。

所以Druid可以:
1、充當數據庫連接池。
2、可以監控數據庫訪問性能
3、獲得SQL執行日志

配置:

pom.xml中添加

        <!--druid連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>

application.yml中添加

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/springBootdemo?characterEncoding=utf-8&useSSL=false
    druid:
      initialSize: 1 #初始化時建立物理連接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時
      minIdle: 1  #最小連接池數量
      maxActive: 20 #最大連接池數量
      maxWait: 60000 #獲取連接時最大等待時間,單位毫秒。配置了maxWait之后,缺省啟用公平鎖,並發效率會有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1
      testWhileIdle: true
      testOnBorrow: true
      testOnReturn: false
      poolPreparedStatements: true  #是否緩存preparedStatement,也就是PSCache。PSCache對支持游標的數據庫性能提升巨大,比如說oracle。在mysql5.5以下的版本中沒有PSCache功能,建議關閉掉。5.5及以上版本有PSCache,建議開啟。
      maxPoolPreparedStatementPerConnectionSize: 20
      filters: stat,wall  #屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:監控統計用的filter:stat,日志用的filter:log4j, 防御sql注入的filter:wall
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      stat-view-servlet:
        allow: 47.111.96.214


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM