1. 程式人生 > >資料庫連線池---DBCP

資料庫連線池---DBCP

資料庫連線池---DBCP

最開始,當然是要將三個支援包導進來才能使用該連線池的,三個包分別為:

apache.commons.pool-1.5.3.jar、commons-dbcp-1.4.jar、mysql-connector-java-5.1.5-bin.jar


我在後面會使用到一個配置檔案,我在這裡先把它貼上來了:dbcp.properties

#mysql
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///mydata?useUnicode=true&characterEncoding=utf-8
username=root
password=
因為我沒有設定密碼,因此密碼這裡空。


然後就開始講了

DbcpPoolDemo.java

package cn.hncu.dbcp;

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

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;

public class DbcpPoolDemo {
	//純Java方式設定引數,使用dbcp池
	@Test
	public void testDbcp() throws Exception{
		BasicDataSource pool=new BasicDataSource();
		pool.setUsername("root");
		pool.setPassword("");
		pool.setDriverClassName("com.mysql.jdbc.Driver");
		pool.setUrl("jdbc:mysql://127.0.0.1:3306/mydata?useUnicode=true&characterEncoding=utf-8");
		
		System.out.println(pool.getMaxActive());//最多能有多少個Connection
		System.out.println(pool.getInitialSize());//初始化時有幾個Connection
		System.out.println( pool.getMaxIdle() ); //最大空閒時間。如果一個使用者獲取一個連線,不用,多長時間會被強行收回
		System.out.println( pool.getMaxWait() ); //等待多長時間,超過該時間就算超時,丟擲異常
		System.out.println("-----------------");
		
		pool.setMaxActive(10);//可以我們自己設定池的相關引數,如最大連線數
		//從池中獲取連線
		for (int i=0;i<20;i++){
			Connection con=pool.getConnection();
			System.out.println(con.hashCode());
			if (i%2==0){
				con.close();
			}
		}
	}
	
	//通過配置檔案方式設定引數,使用dbcp池
	@Test
	public void testPropertyFile() throws Exception{
		Properties p=new Properties();
		//p.load(DbcpPoolDemo.class.getClassLoader().getResourceAsStream("dbcp.properties"));//配置檔案要放在src(bin)的根目錄---classpath的根
		p.load(DbcpPoolDemo.class.getResourceAsStream("dbcp.properties"));//配置檔案和當前類的class放在一起
		DataSource pool=BasicDataSourceFactory.createDataSource(p);
		//從它的池中獲取連線
		for (int i=0;i<20;i++){
			Connection con=pool.getConnection();
			System.out.println(con.hashCode());
			if (i%2==0){
				con.close();
			}
		}
	}
}


上面的程式碼中已經提到了如何使用,在這裡我就進行補充說明:

關於dbcp的close方法呼叫後,該Connection就會真的關了,變為null不能使用了;池中只能放設定好的數量Connection,若一直不close或還回來將一直佔用,誰要拿都拿不到。


在上面程式碼中可以證實上面補充的內容:

我都以上面程式碼的testDbcp()方法為例

1、關於呼叫close就真的關了:

按照上面的程式碼,輸出會是這樣的


一看到下面這樣的hash值很多人會很疑惑,為什麼關了之後還是原來的hash值,再下一個就不是了。

那麼我們把程式碼位置換一下,換成這樣的,結果就很明顯了:

for (int i=0;i<20;i++){
	Connection con=pool.getConnection();
	if (i%2==0){
		con.close();
	}
<span style="white-space:pre">	</span>System.out.println(con.hashCode());
}
結果就是如下了:


我們在這裡輸的是hash值,因此空的就是輸出0,若直接輸出con,就會輸出null

2、佔用不還

這個很好證明,我們只要不呼叫close就好,因為我們這裡也沒有寫還回去的方法

我們只需要將程式碼改成如下即可:

for (int i=0;i<20;i++){
	Connection con=pool.getConnection();

<span>	</span>System.out.println(con.hashCode());
}
結果如下:



當然了,這個可以做成一個工具類供資料庫連線時使用的,如下我做了一個:

package cn.hncu.dbcp;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DbcpUtil {
	private static DataSource pool;
	private static ThreadLocal<Connection> t=new ThreadLocal<Connection>();
	static {
		try {
			Properties p=new Properties();
			p.load(DbcpUtil.class.getResourceAsStream("dbcp.properties"));// 配置檔案和當前類的class放在一起<pre name="code" class="java"><span style="white-space:pre">			</span>//p.load(DbcpPoolDemo.class.getClassLoader().getResourceAsStream("dbcp.properties"));//配置檔案要放在src(bin)的根目錄---classpath的根
pool=BasicDataSourceFactory.createDataSource(p);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}public static DataSource getDataSource(){return pool;}public static Connection getConnection() throws SQLException{Connection con=t.get();if (con==null){con=pool.getConnection();t.set(con);}return con;}}