資料庫連線池---DBCP
阿新 • • 發佈:2018-11-29
資料庫連線池---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;}}