1. 程式人生 > >設定JDBC資料庫連線池

設定JDBC資料庫連線池

前言

    JDBC作為J2EE的規範之一,它定義了連線資料庫的介面,封裝了連線資料庫的細節問題,給開發人員極大的方便。開發人員只需要實現這些介面,就可以連線不同的資料庫,不需要針對不同資料庫寫不同的連線程式碼。

JDBC連線資料庫

    JDBC連線資料庫,簡單來說有下面四個步驟:

        1、載入資料庫驅動

        2、建立連線

        3、訪問資料庫

        4、關閉資料庫連線

    當然,JDBC連線資料庫沒有這麼簡單,它還包括Statement物件的建立,如果需要,還會建立ResultSet物件,關閉連線的時候,也要相應的先關閉其他物件,如《

看JDBC輕鬆連線資料庫,你值得擁有》中,有詳細介紹。如果採用單個連線的話,Web的每一次請求都會建立資料庫連線,這樣既浪費資源又浪費時間,所以就採用了連線池的技術。將資料庫連線放入連線池中,訪問資料庫時去連線池中取連線,用完之後就將連線放回連線池。

連線池

    資料庫連線池又稱Resource Pool,基本思想是為資料庫連線建立一個緩衝池,當建立連線池時,預先在連線池中配置一些數量的連線,當需要建立資料庫連線時,就在連線池中取出連線,用完之後再放進去,否則當使用連線數超過最大連線數,接著再請求連線時,就會出現Timeout異常。當需要建立的連線數超過連線池中預先放入的連線,再建立新的連線。當然,連線池可以設定它的最大連線數,以及初始化時的連線數。

    JDBC並未提供連線池的方法,我們可以採用Tomcat,對連線池的一些引數進行設定。我們可以通過進入Tomcat的管理介面進行設定,或者直接設定Tomcat的server.xml檔案,因為管理介面設定完成後,同樣也會寫入server.xml檔案中。如果採用xml檔案直接配置,就需要把下面的程式碼放入server.xml檔案中,然後修改相應的引數就可以了。設定連線池的時候,有幾個固定的引數:

<Resource
      name="jdbc/drp"
      type="javax.sql.DataSource"
      maxActive="4"
      maxIdle="2"
      username="drp1"
      maxWait="5000"
      driverClassName="oracle.jdbc.driver.OracleDriver"
      password="123456"
      url="jdbc:oracle:thin:@localhost:1521:orcl"/>

    driverClassName:表示資料庫驅動,上面程式碼中是Oracle驅動,如果是Mysql資料庫,只需改成Mysql的驅動類就好了

    url:資料庫路徑,如果是連線伺服器的資料庫,只需要將localhost改成伺服器IP地址就OK了

    username:username是資料庫的使用者名稱

    password:是該使用者的密碼

    maxActive:最大的可用的連線數量

    maxIdle:初始化時,連線池中的空閒連線數

    maxWait:最長等待時間,如果超過這個時間沒有獲得連線(單位為ms),則提示Timeout

    name:是隨便起的名字

    type:指的是實現的javax.sql.DataSource的介面,是JDBC提供的

    配置完成之後,該連線池就對Tomcat伺服器下的所有程式起作用。如果想讓該連線池設定只對某一個應用程式起作用,只需要將上述程式碼拷貝到tomcat/conf路徑下的context.xml檔案中,然後將該檔案剪下到應用程式的WebRoot/META-INF路徑下即可。

    當需要建立連線池時,直接去連線池中取就好了:

Connection conn = null;
try { 
	Context ctx = new InitialContext();
	//通過JNDI查詢DataSource
 	DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/drp");
 	conn = ds.getConnection();
}catch(Exception e) {
	e.printStackTrace();
	throw new ApplicationException("系統錯誤,請聯絡系統管理員");
} 
return conn;

執行緒併發問題

    資料庫連線池並不是執行緒安全的,所以我們可以在建立Connection時可以採用synchronized關鍵字來保證執行緒同步,也可以採用ThreadLocal進行管理。當一個方法需要建立資料庫連線時,可以先判斷它所在的執行緒是否已經綁定了一個Connection,如果已經綁定了,那就直接用,如果沒有,就建立一個Connection物件,放到ThreadLocal中,以備後面的方法使用。

private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();
/**
 * 得到Connection
 * @return
 */
public static Connection getConnection() {
	Connection conn = connectionHolder.get();
	//如果在當前執行緒中沒有繫結相應的Connection
	if (conn == null) {
		//建立一個新連線
		conn = DbUtil.getConnection();
		//將連線放入ThreadLocal
		connectionHolder.set(conn);
	}
	return conn;
}
當然,關閉連線時,也需要把Connection從ThreadLocal中移除出去:
public static void closeConnection() {
	Connection conn = connectionHolder.get();
	if (conn != null) {
		try {
			conn.close();
			//從ThreadLocal中清除Connection
			connectionHolder.remove();
		} catch (SQLException e) {
			e.printStackTrace();
		}	
	}
}

總結

    JDBC作為一個規範,它將連線資料庫的細節封裝了起來,提供給我們各種介面,只要去實現這些介面,就可以實現資料庫的連線。JDBC連線資料庫有固定的步驟,而每建立一個連線都需要執行這個過程,對於訪問人數較多的網站來說,如果不對資料庫連線進行限制的話,系統會一直建立連線,這樣就會造成資料庫的記憶體洩露,對資料安全造成問題,所以就採用了連線池技術做改善,在連線池中限制最大連線數,只允許程式建立一定量的連線,用完之後就一定要放回連線池。即使這樣,也會出現多執行緒併發問題,對於執行緒同步,可以採用synchronized關鍵字,也可以使用ThreadLocal來解決。