我們應該知道,在進行數據庫連接的時候,是極其消耗時間和性能的。如果每次對數據庫進行操作,都要進行一次Connection,那麼,可想而知,性能有多麼的差。你要知道,一個大型的web應用,同一時間就可能有成千上萬個訪問數據庫的請求,並且數據庫服務器能供同時創建的Connection數目也是有限的。
因此,問題來了。怎麼最大限度的利用這些有限資源呢?
數據庫連接池的技術出現,解決了這一問題。連接池技術就是預先創建多個連接對象,保存到連接池中,當有客戶請求時,從池中取出一個連接對象爲客戶服務,當請求完成後,客戶程序調用close方法,將連接對象歸還給連接池,已備其他客戶使用,而不是真正的斷開連接。這樣就避免了每次請求都創建連接對象所帶來的性能開銷。
我這裏簡單的介紹一下常用的連接池技術:DBCP,C3P0,還有阿里的Druid。
1.DBCP
DBCP(DataBase connection pool)數據庫連接池。是 Apache 上的一個 Java 連接池項目,也是 tomcat 使用的連接池組件。單獨使用DBCP需要2個包:commons-dbcp.jar和commons-pool.jar。由於建立數據庫連接是一種非常耗時、耗資源的行爲,所以通過連接池預先同數據庫建立一些連接,放在內存中,應用程序需要建立數據庫連接時直接到連接池中申請一個就行,使用完畢後再歸還到連接池中。數據庫連接的釋放和斷開,由程序自動管理,大大方便了開發人員。
我使用的是dbcp2.0版本以上的jar包,如下:
不管使用哪種連接池技術,原理都是一樣的,而常用的配置都是一樣的,頂多配置參數的名稱不同而已。下面介紹一下dbcp2.0版本以上的常用的配置參數(配置信息是寫在src下的db.properties中的形式)
#要連接的數據庫的driverClassName
driverClassName=com.mysql.jdbc.Driver
#要傳遞給JDBC驅動程序以建立連接的連接URL。
url=jdbc:mysql://localhost:3306/db_test
#要傳遞給JDBC驅動程序以建立連接的連接用戶。
username=root
#要傳遞給JDBC驅動程序以建立連接的連接密碼。
password=mmforu
#同時從這個池中分配的活動連接的最大數量,或者爲負,沒有限制。dbcp1.0叫maxActive
maxTotal=20
#啓動連接池時創建的初始連接數。
initialSize=1
#池在拋出異常之前(當沒有可用連接時)等待返回連接的最大毫秒數,或者<= 0無限期等待。
maxWaitMillis=60000
#最大空閒連接:連接池中容許保持空閒狀態的最大連接數量,超過的空閒連接將被釋放,如果設置爲負數表示不限制
maxIdle=8
#池中可以保持空閒的活動連接的最小數量
minIdle=3
封裝一個DBUtil工具類:
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp2.BasicDataSource;
public class DBUtil {
//定義一個靜態的連接池對象
private static BasicDataSource pool = new BasicDataSource();
static {
try {
//創建一個Properties對象,加載db.properties裏的配置信息
Properties prop = new Properties();
InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
//加載配置信息
prop.load(is);
//設置連接池常用屬性
pool.setDriverClassName(prop.getProperty("driverClassName"));
pool.setUrl(prop.getProperty("url"));
pool.setUsername(prop.getProperty("username"));
pool.setPassword(prop.getProperty("password"));
pool.setMaxTotal(Integer.parseInt(prop.getProperty("maxTotal")));
pool.setInitialSize(Integer.parseInt(prop.getProperty("initialSize")));
pool.setMaxWaitMillis(Long.parseLong(prop.getProperty("maxWaitMillis")));
pool.setMaxIdle(Integer.parseInt(prop.getProperty("maxIdle")));
pool.setMinIdle(Integer.parseInt(prop.getProperty("minIdle")));
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return pool.getConnection();
}
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
Connection conn = getConnection();
System.out.println(conn);
close(conn);
} catch (Exception e) {
e.printStackTrace();
}
}
}
工具類寫好了,對數據庫的增刪改查操作,這裏就不做測試了!!!!沒有必要。
2.C3P0
關於c3p0的配置,我這裏只介紹xml配置文件的寫法。至於properties配置文件的寫法就不累述了,參考上述的dbcp,稍微注意一下參數名就行了。種是通過在同src目錄下的c3p0-conflg.xml文件或者c3p0.properties文件進行相關的配置。
我用的是如下jar包
我們將c3p0-config.xml文件放置在src目錄下,常用屬性如:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默認配置,如果沒有指定則使用這個配置 -->
<default-config>
<property name="user">root</property>
<property name="password">mmforu</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db_test</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 當連接池中的連接用完時,C3P0一次性創建新連接的數目 -->
<property name="acquireIncrement">10</property>
<!-- 連接池中保留的最大連接數 -->
<property name="maxPoolSize">50</property>
<!-- 連接池中保留的最小連接數 -->
<property name="minPoolSize">2</property>
<!-- 初始化時創建的連接數,應在minPoolSize與maxPoolSize之間取值。默認爲3; -->
<property name="initialPoolSize">5</property>
<!-- 最大空閒時間,超過空閒時間N秒的連接將被丟棄。爲0或負數則永不丟棄。默認爲0; -->
<property name="maxIdleTime">600</property>
</default-config>
</c3p0-config>
封裝DBUtil工具類
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DBUtil {
//定義一個靜態的c3p0的連接池屬性,利用構造器加載src下的配置文件,c3p0會自動裝置配置信息
private static ComboPooledDataSource pool = new ComboPooledDataSource("c3p0-config");
/**
* 獲取連接池中的一個連接對象
*/
public static Connection getConnection() throws SQLException {
return pool.getConnection();
}
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//測試連接
public static void main(String[] args) throws SQLException {
Connection conn = getConnection();
System.out.println(conn);
close(conn);
}
}
同樣的,我不做測試了。
3.Druid
Druid是阿里巴巴開發的號稱爲監控而生的數據庫連接池,Druid是目前最好的數據庫連接池,在功能、性能、擴展性方面,都超過其他數據庫連接池,同時加入了日誌監控,可以很好的監控DB池連接和SQL的執行情況。
我使用的jar包是:
可以使用properties配置文件,將db.properties配置文件放在src目錄下:
driverClassName=com.mysql.jdbc.Driver
jdbcurl=jdbc:mysql://localhost:3306/db_test
username=root
password=mmforu
#啓動連接池時,初始化連接的個數
initialSize=5
#連接池中最大連接數
maxActive=20
#獲取連接時最大等待時間,單位毫秒。配置了maxWait之後,缺省啓用公平鎖,併發效率會有所下降,如果需要可以通過配置useUnfairLock屬性爲true使用非公平鎖。
maxWait=3000
#最大空閒連接數,已經棄用,配置了也沒作用
maxIdle=6
#最小空閒連接數
minIdle=3
編寫DBUtil工具類:
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DBUtil {
private static DataSource source;
static {
try {
Properties prop = new Properties();
prop.load(DBUtil.class.getClassLoader().getResourceAsStream("db3.properties"));
//調用工廠類的靜態方法,獲取連接池
source = DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return source.getConnection();
}
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws SQLException {
Connection conn = getConnection();
System.out.println(conn);
close(conn);
}
}
ok,如果想要知道三個連接池技術的詳細參數,請先百度吧,等有時間,我再整理他們的詳細參數。
--------------------------------------------------------------------------如有疑問,敬請留言---------------------------------------------------------------------------