一、数据库连接池的概述
1、数据库连接池的由来:
- 使用DriverManager创建连接的问题:每次调用都创建一个新连接,没有复用连接,效率低,它没有控制连接的上限,并发量大的时候可能会导致数据库崩溃。
2、数据库连接池(Connection pooling):
- 是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
3、数据库连接池作用:
- 能复用连接,提高效率;能控制连接的上限,避免数据库崩溃。
DBCP(DataBase connection pool)、C3P0、Druid等
二、数据库连接池的原理
- 初始化连接池时,它会自动创建一批(配)连接,并标记为空闲态;
- 当调用它获取一个连接时,它会返回一个连接,并标记为占用态;
- 当归还连接时,连接池会将其内部数据清空,并标记为空闲态;
- 当连接池发现连接快不够用(配)时,它会再创建一批(配)连接;
- 当占用连接达到上限(配)时,连接池会让新用户等待;
- 当高峰期过后,连接池会自动关闭一批(配)连接。
三、常用数据库连接池
1、DBCP连接池
- jar包:commons-dbcp-1.4.jar和commons-pool-1.6.jar
- 配置文件db.properties:
# db connection parameters
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true&useSSL=true
username=root
password=123456
# initialized connections
initialSize=5
# maximum connection
maxActive=10
# timeout time
maxWait=3000
- DBCP连接池的使用:
package com.wedu.demo;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* DBCP数据库连接池工具类
*/
public class DBCPUtils {
private static DataSource ds = null;
static {
Properties prop = new Properties();
try {
//1、加载配置文件
prop.load(DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties"));
//2、创建数据库连接池对象
ds = BasicDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池对象
* @return
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取数据库连接对象
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* 释放资源
* @param st
* @param conn
*/
public static void close(Statement st,Connection conn){
close(null,st,conn);
}
/**
* 释放资源
* @param rs
* @param st
* @param conn
*/
public static void close(ResultSet rs,Statement st, Connection conn){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2、C3P0连接池
- jar包:c3p0-0.9.5.2.jar和mchange-commons-java-0.2.12.jar
- 配置文件:c3p0.properties
# db connection parameters
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true&useSSL=true
c3p0.user=root
c3p0.password=123456
# initialized connections
c3p0.initialPoolSize=5
# maximum connection
c3p0.maxPoolSize=10
# timeout time
c3p0.checkoutTimeout=3000
- 配置文件c3p0-config.xml
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<!--初始化申请的连接数量-->
<property name="initialPoolSize">5</property>
<!--最大的连接数量-->
<property name="maxPoolSize">10</property>
<!--超时时间-->
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db3</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
- C3P0连接池使用
package com.wedu.demo;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* C3P0数据库连接池工具类
*/
public class C3P0Utils {
private static DataSource ds = new ComboPooledDataSource();
/**
* 获取连接池对象
* @return
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取数据库连接对象
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* 释放资源
* @param st
* @param conn
*/
public static void close(Statement st,Connection conn){
close(null,st,conn);
}
/**
* 释放资源
* @param rs
* @param st
* @param conn
*/
public static void close(ResultSet rs,Statement st, Connection conn){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3、Druid连接池
- jar包:druid-1.1.10.jar
- 配置文件:db.properties
# db connection parameters
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true&useSSL=true
username=root
password=123456
# initialized connections
initialSize=5
# maximum connection
maxActive=10
# timeout time
maxWait=3000
- Druid连接池的使用
package com.wedu.demo;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* Druid数据库连接池工具类
*/
public class DruidUtils {
private static DataSource ds = null;
static {
Properties prop = new Properties();
try {
//1、加载配置文件
prop.load(DruidUtils.class.getClassLoader().getResourceAsStream("db.properties"));
//2、创建数据库连接池对象
ds = DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池对象
* @return
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取数据库连接对象
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* 释放资源
* @param st
* @param conn
*/
public static void close(Statement st,Connection conn){
close(null,st,conn);
}
/**
* 释放资源
* @param rs
* @param st
* @param conn
*/
public static void close(ResultSet rs,Statement st, Connection conn){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}