JDBC數據庫連接池
數據庫創建鏈接是比較消耗資源的,訪問量非常高的情況會造成內存溢出等等負面影響。
大部分數據鏈接池解決了這個問題,一般的實現思路是這樣得:
- 鏈接池在初始化時首先獲取一定數量得鏈接并保存起來,程序請求鏈接時,直接由連接池返回一個,應用程序使用完后再歸還給鏈接池。
常用的開源鏈接池:
DBCP
dbcp是apache的,tomcat也采用了此鏈接池。
使用需要導入兩個包
commons-dbcp.jar
commons-pool.jar
使用示例(模板代碼)
為了使代碼層次更清晰,減少耦合度并增加復用性,我們會將數據庫鏈接的類單獨抽取出來,它屬于工具類,可以歸為工具包中的類(比如:utils.JdbcUitls.java)
dbcp將數據庫配置相關的信息單獨存放在.properties配置文件中,我們只需要將dbcp示例中的.properties文件考入工程中。
dbcpconfig.propertes :
#連接設置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/day17 username=root password=hang #<!-- 初始化連接 --> initialSize=10 #最大連接數量 maxActive=50 #<!-- 最大空閑連接 --> maxIdle=20 #<!-- 最小空閑連接 --> minIdle=5 #<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等于60秒 --> maxWait=60000 #JDBC驅動建立連接時附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;] #注意:"user" 與 "password" 兩個屬性會被明確地傳遞,因此這里不需要包含他們。 connectionProperties=useUnicode=true;characterEncoding=utf8 #指定由連接池所創建的連接的自動提交(auto-commit)狀態。 defaultAutoCommit=true #driver default 指定由連接池所創建的連接的只讀(read-only)狀態。 #如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動并不支持只讀模式,如:Informix) defaultReadOnly= #driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。 #可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_COMMITTED
配置好了,我們需要創建一個工具類,這個工具類自己封裝了數據庫鏈接池的實現,并向外提供了一個返回數據庫連接的方法
JdbcUitls.java
public class JdbcUtils {
//DataSource是DBCP的數據庫連接池
private static DataSource ds=null;
//既然是工具類,那就是拿來就能用的,不用new它
//這個靜態代碼塊確保其內容只運行一次,這里在第一次調用的時候,獲取一個工廠
static{
try{
//讀取資源文件
Properties prop =new Properties();
JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
//DBCP的連接池工廠
BasicDataSourceFactory factory=new BasicDataSourceFactory();
//通過這個工廠,我們獲得一個根據資源文件配置的數據庫連接池
ds = factory.createDataSource(prop);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
//返回一個數據庫連接
public static Connection getConnection() throws SQLException{
//從DataSource中獲取一個空閑得連接并返回給調用它的方法
return ds.getConnection();
}
}
這樣我們在獲取連接的時候可以直接通過這個靜態類獲得,在使用完成后,保持良好的習慣去關閉這個連接,這個連接實質上不會關閉,會被連接池收回,DBCP使用了動態代理來截斷調用者對Connection.close()方法得直接操作。
C3P0
c3p0與dbcp一樣都是讀取配置文件
配置文件 c3p0-config.xml :
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb</property> <property name="user">root</property> <property name="password">root</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> <property name="maxStatements">200</property> </default-config> <-- named-config可以采取多個配置 --> <named-config name="mysql"> <property name="acquireIncrement">50</property> <property name="initialPoolSize">100</property> <property name="minPoolSize">50</property> <property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching --> <property name="maxStatements">0</property> <property name="maxStatementsPerConnection">5</property> </named-config> </c3p0-config>
示例:
JdbcUtils_C3P0.java
public class JdbcUtils_C3PO {
private static ComboPooledDataSource ds;
static{
try{
//這個是加載配置文件
ds = new ComboPooledDataSource();
//這個手動設置,不加載配置文件
/*ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/day16");
ds.setUser("root");
ds.setPassword("root");
ds.setInitialPoolSize(20);*/
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
}
浙公網安備 33010602011771號