連接池的作用及講解


連接池的作用就是為了提高性能。

       連接池的作用:連接池是將已經創建好的連接保存在池中,當有請求來時,直接使用已經創建好的連接對數據庫進行訪問。這樣省略了創建連接和銷毀連接的過程。這樣性能上得到了提高。

基本原理是這樣的:

1)建立數據庫連接池對象(服務器啟動)。
2)按照事先指定的參數創建初始數量的數據庫連接(即:空閑連接數)。
3)對於一個數據庫訪問請求,直接從連接池中得到一個連接。如果數據庫連接池對象中沒有空閑的連接,且連接數沒有達到最大(即:最大活躍連接數),創建一個新的數據庫連接。
4)存取數據庫。
5)關閉數據庫,釋放所有數據庫連接(此時的關閉數據庫連接,並非真正關閉,而是將其放入空閑隊列中。如實際空閑連接數大於初始空閑連接數則釋放連接)。
6)釋放數據庫連接池對象(服務器停止、維護期間,釋放數據庫連接池對象,並釋放所有連接)。

1 .連接池的概念和為什么要使用連接池?
    連接池放了N個Connection對象,本質上放在內存當中,在內存中划出一塊緩存對象,應用程序每次從池里獲得Connection對象,而不是直接從數據里獲得,這樣不占用服務器的內存資源。

2 .如果不使用連接池會出現的情況:
a.占用服務器的內存資源
b.導致服務器的速度非常慢

3 .應用連接池的三種方式:
a.自定義連接池
b.使用第三方連接池
c.使用服務器自帶的連接池

       連接池一般比直接連接更有優越性,因為它提高了性能的同時還保存了寶貴的資源。在整個應用程序的使用過程,當中重復的打開直接連接將導致性能的下降。而池連接只在服務器啟動時打開一次,從而消除了這種性能問題。
        連接池主要考慮的是性能,每次獲取連接和釋放連接都有很大的工作量,會對性能有很大影響;而對資源來說起的是反作用,因為保存一定數量的連接是要消耗內存的。應用程序每次從池里獲得Connection對象,而不是直接從數據里獲得,這樣不占用服務器的內存資源。所以一般要建立連接池,而連接的數量要適當,不能太大,太大會過多消耗資源。(所以,考慮2個方面,一個是內存,另一個是資源)。

       連接池就是為了避免重復多次的打開數據庫連接而造成的性能的下降和系統資源的浪費。

接下來,我們來學習三種連接池的配置:dbcp、c3p0、druid

1、dbcp連接池

連接配置文件

#數據庫驅動
driverClassName=com.mysql.jdbc.Driver
#數據庫連接地址
url=jdbc:mysql://localhost/ctg
#用戶名
username=root
#密碼
password=123456

#連接池的最大數據庫連接數。設為0表示無限制
maxActive=30
#最大空閑數,數據庫連接的最大空閑時間。超過空閑時間,數據庫連
#接將被標記為不可用,然后被釋放。設為0表示無限制
maxIdle=10
#最大建立連接等待時間。如果超過此時間將接到異常。設為-1表示無限制
maxWait=1000

#超過removeAbandonedTimeout時間后,是否進 行沒用連接(廢棄)的回收(默認為false,調整為true) 
removeAbandoned=true
#超過時間限制,回收沒有用(廢棄)的連接(默認為 300秒,調整為180)
removeAbandonedTimeout=180


連接池管理類

package cn.songxinqiang.samples.commonsdbcp.util;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;

/**
 * tomcat數據庫連接池管理類<br>
 * 使用為tomcat部署環境<br>
 * 需要在類路徑下准備數據庫連接配置文件dbcp.properties
 * 
 * @author 宋信強
 * @mail songxinqiang123@gmail.com
 * 
 * @time 2013-12-27
 * 
 */
public class DBManager {
 private static final Log log = LogFactory.getLog(DBManager.class);
 private static final String configFile = "dbcp.properties";

 private static DataSource dataSource;

 static {
  Properties dbProperties = new Properties();
  try {
   dbProperties.load(DBManager.class.getClassLoader()
     .getResourceAsStream(configFile));
   dataSource = BasicDataSourceFactory.createDataSource(dbProperties);

   Connection conn = getConn();
   DatabaseMetaData mdm = conn.getMetaData();
   log.info("Connected to " + mdm.getDatabaseProductName() + " "
     + mdm.getDatabaseProductVersion());
   if (conn != null) {
    conn.close();
   }
  } catch (Exception e) {
   log.error("初始化連接池失敗:" + e);
  }
 }

 private DBManager() {
 }

 /**
  * 獲取鏈接,用完后記得關閉
  * 
  * @see {@link DBManager#closeConn(Connection)}
  * @return
  */
 public static final Connection getConn() {
  Connection conn = null;
  try {
   conn = dataSource.getConnection();
  } catch (SQLException e) {
   log.error("獲取數據庫連接失敗:" + e);
  }
  return conn;
 }

 /**
  * 關閉連接
  * 
  * @param conn
  *            需要關閉的連接
  */
 public static void closeConn(Connection conn) {
  try {
   if (conn != null && !conn.isClosed()) {
    conn.setAutoCommit(true);
    conn.close();
   }
  } catch (SQLException e) {
   log.error("關閉數據庫連接失敗:" + e);
  }
 }

}

 

 

以上是dbcp連接池的配置和使用方式,以上的方式僅供參考。

 

2、c3p0連接池

 

數據庫連接配置

c3p0.jdbcUrl=jdbc:oracle:thin:@127.0.0.1:1521:orcl c3p0.driverClass=oracle.jdbc.driver.OracleDriver c3p0.user=test c3p0.password=test

c3p0.acquireIncrement=3  c3p0.idleConnectionTestPeriod=60  c3p0.initialPoolSize=10  c3p0.maxIdleTime=60  c3p0.maxPoolSize=20  c3p0.maxStatements=100  c3p0.minPoolSize=5 


C3P0獲取連接公共類

public class MyC3P0Utils{
	private static DataSource ds;

	private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
	static {
		ds = new ComboPooledDataSource();//直接使用即可,不用顯示的配置,其會自動識別配置文件
	}

	public static DataSource getDataSource() {
		return ds;
	}

	public static Connection getConnection() {
		try {
//			 得到當前線程上綁定的連接
			Connection conn = tl.get();
			if (conn == null) { // 代表線程上沒有綁定連接
				conn = ds.getConnection();
				tl.set(conn);
			}
			return conn;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void startTransaction() {
		try {
			// 得到當前線程上綁定連接開啟事務
			Connection conn=getConnection();
			conn.setAutoCommit(false);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void commitTransaction() {
		try {
			Connection conn = tl.get();
			if (conn != null) {
				conn.commit();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void closeConnection() {
		try {
			Connection conn = tl.get();
			if (conn != null) {
				conn.close();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			tl.remove(); // 千萬注意,解除當前線程上綁定的鏈接(從threadlocal容器中移除對應當前線程的鏈接)
		}
	}
}


 

另外提醒一下:不要忘記導入jar包

導入C3P0相關jar包

 

上面就是c3p0連接池的配置方式,僅供參考哦!

當然連接池的配置方式是不同的,上面配置的方式都是將配置放入到property的文件中,還有一種就是使用XML文件的方式,這里不介紹了。

 

下面來講解到druid連接池的配置方法

 

配置文件

driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@192.168.97.51:1521:lc8
username=admin8
password=adminpwd8
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200


測試連接:

 

package taobao_druid;

import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

/**  * The Class DataSourceUtil.  */ public class DataSourceUtil {

    /** 使用配置文件構建Druid數據源. */     public static final int DRUID_MYSQL_SOURCE = 0;

    /** 使用配置文件構建Druid數據源. */     public static final int DRUID_MYSQL_SOURCE2 = 1;

    /** 使用配置文件構建Dbcp數據源. */     public static final int DBCP_SOURCE = 4;     public static String confile = "druid.properties";     public static Properties p = null;

    static {         p = new Properties();         InputStream inputStream = null;         try {             //java應用             confile = DataSourceUtil.class.getClassLoader().getResource("").getPath()                     + confile;             System.out.println(confile);             File file = new File(confile);             inputStream = new BufferedInputStream(new FileInputStream(file));             p.load(inputStream);         } catch (Exception e) {             e.printStackTrace();         } finally {             try {                 if (inputStream != null) {                     inputStream.close();                 }             } catch (IOException e) {                 e.printStackTrace();             }         }     }

    /**      * 根據類型獲取數據源      *      * @param sourceType      *            數據源類型      * @return druid或者dbcp數據源      * @throws Exception      *             the exception      */     public static final DataSource getDataSource(int sourceType) throws Exception {         DataSource dataSource = null;         switch (sourceType) {         case DRUID_MYSQL_SOURCE:             dataSource = DruidDataSourceFactory.createDataSource(p);             break;         case DRUID_MYSQL_SOURCE2:             dataSource = DruidDataSourceFactory.createDataSource(p);             break;         case DBCP_SOURCE:             // dataSource = BasicDataSourceFactory.createDataSource(             // MySqlConfigProperty.getInstance().getProperties());             break;         }         return dataSource;     } }


 

 

上面就是三種配置連接池的方式,相信大家也學到了很多,Me Too!

版權聲明:感覺我寫的還算不錯的的話希望你能夠動動你的鼠標和鍵盤為我點上一個贊或是為我奉獻上一個評論,在下感激不盡!_______________________________________________________歡迎轉載,希望在你轉載的同時,添加原文地址,謝謝配合


免責聲明!

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



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