web项目都会使用数据库,而数据库访问会影响系统性能(I/O操作)。建立数据库连接是一个非常耗时耗资源的操作,通过配置连接池可以在系统启动时就分配并维护一定数量的连接,保持最低数量的连接数,通过设定连接池最大连接数来防止系统无尽的与数据库连接。这样在每次数据请求方需要连接时,直接从连接池获取,使用完毕之后再放回去,这样就可以尽可能减少不必要的数据库连接消耗,缓解数据库的访问压力,减轻对系统性能的影响。
java常用的数据库连接池主要有 DBCP 和 C3P0;
一、DBCP
DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 Java 连接池项目,也是Tomcat 在 7.0 以前的版本使用的连接池组件。
使用DBCP应该导入commons-dbcp-x.x.jar、commons-pool-x.x.jar、commons-logging-x.x.jar
commons-dbcp最新版本是Apache Commons DBCP 2.1.1 for JDBC 4.1 (Java 7.0+)
Apache Commons Pool 2.4.2 (Java 6.0+)
测试实例
TestDBCP.java
package cn.iborder.utils;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.junit.Test;
public class TestDBCP {
//硬编码方式实现连接池
@Test
public void test1() {
Connection con = null;
PreparedStatement pstat = null;
ResultSet rs = null;
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/test");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setInitialSize(3);
//dataSource.setMaxActive(6); //DBCP2.0以上版本已经移除此方法,由 setMaxTotal()代替
dataSource.setMaxTotal(6); //最大连接数
dataSource.setMaxIdle(5); //最大空闲连接数.
dataSource.setMinIdle(4);
try {
con = dataSource.getConnection();
pstat = con.prepareStatement("select * from admin");
rs = pstat.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(rs != null){
rs.close();
rs=null;
}
if(pstat != null){
pstat.close();
pstat=null;
}
if (con != null && !con.isClosed()) {
con.close();
con=null;
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
//配置文件方式实现连接池
@Test
public void test2() {
Connection con = null;
PreparedStatement pstat = null;
ResultSet rs = null;
try {
Properties prop = new Properties();
BufferedInputStream in = (BufferedInputStream) this.getClass().getResourceAsStream("/db.properties");
//FileInputStream in = (FileInputStream) TestDBCP.class.getResourceAsStream("/db.properties");//抛异常
prop.load(in);
DataSource dataSource = BasicDataSourceFactory.createDataSource(prop);
con = dataSource.getConnection();
pstat = con.prepareStatement("select * from admin");
rs = pstat.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(rs != null){
rs.close();
rs=null;
}
if(pstat != null){
pstat.close();
pstat=null;
}
if (con != null && !con.isClosed()) {
con.close();
con=null;
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
db.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/test
username=root
password=root
InitialSize=3
MaxTotal=6
MaxIdle=5
MinIdle=4
二、C3P0
C3P0是一个开放源代码的JDBC连接池,最常用的连接池技术,Spring/Hibernate框架默认支持C3P0
使用C3P0 应该导入c3p0.xxxx.jar和mchange-commons-java-x.x.x.jar
C3P0最新版本是C3P0 0.9.5.2
核心类:CombopooledDataSource
测试实例
TestC3P0.java
package cn.iborder.utils;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class TestC3P0 {
//硬编码方式实现连接池
@Test
public void test1(){
Connection con = null;
PreparedStatement pstat = null;
ResultSet rs = null;
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost/test");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setInitialPoolSize(3);
dataSource.setMaxPoolSize(6);
dataSource.setMaxIdleTime(1000);
con = dataSource.getConnection();
pstat = con.prepareStatement("select * from admin");
rs = pstat.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
}
} catch (PropertyVetoException e) {
// TODO: handle exception
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(rs != null){
rs.close();
rs=null;
}
if(pstat != null){
pstat.close();
pstat=null;
}
if (con != null && !con.isClosed()) {
con.close();
con=null;
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
//配置文件方式实现连接池
@Test
public void test2() {
Connection con = null;
PreparedStatement pstat = null;
ResultSet rs = null;
try {
//读取默认数据库
//ComboPooledDataSource dataSource = new ComboPooledDataSource();
//读取指定name的数据库
ComboPooledDataSource dataSource = new ComboPooledDataSource("otherDB");
con = dataSource.getConnection();
pstat = con.prepareStatement("select * from admin");
rs = pstat.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(rs != null){
rs.close();
rs=null;
}
if(pstat != null){
pstat.close();
pstat=null;
}
if (con != null && !con.isClosed()) {
con.close();
con=null;
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
c3p0-config.xml
<c3p0-config>
<!-- 默认数据库 -->
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">3</property>
<property name="maxPoolSize">6</property>
<property name="maxIdleTime">1000</property>
<user-overrides user="swaldman">
<!--
<property name="unreturnedConnectionTimeout">5</property>
<property name="debugUnreturnedConnectionStackTraces">true</property>
-->
<!-- <property name="preferredTestQuery">select poop from doop</property> -->
<!-- intentionally broken -->
</user-overrides>
</default-config>
<!-- 配置其他是数据库 -->
<named-config name="otherDB">
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">3</property>
<property name="maxPoolSize">6</property>
<property name="maxIdleTime">1000</property>
</named-config>
</c3p0-config>
来源:oschina
链接:https://my.oschina.net/u/2321708/blog/801110