一、为什么需要连接池?
在传统的JDBC开发中,每次操作数据库都需要:
1.加载驱动 2.创建连接 3.执行SQL 4.关闭连接
缺点:需要自己创建连接和销毁连接,这样是比较消耗时间,资源等
有一些连接池,已经创建好了一些连接,现在可以从连接池中获取到,这样就节省创建连接时间,直接使用这些连接,归还到连接池中。
优点:
节省创建连接与释放连接,性能消耗
连接池中连接起到复用的作用,提升程序性能
二、连接池参数(池参数,如果不指定,有默认值)
初始大小:10个
最小空闲连接数:3个
增量:一次创建的最小单位(5个)
最大空闲连接数:12个
最大连接数:20个
最大的等待时间:1000毫秒
三、4个参数
任何的开源的连接池,4大参数都需要自己来设置
* 驱动的名称‐‐ com.mysql.jdbc.Driver
* 连接‐‐ jdbc:mysql:///day14
* 用户名‐‐ root
* 密码‐‐ root
四、DataSource 接口
SUN 公司定义了 javax.sql.DataSource 接口,所有连接池都必须实现它:
java
public interface DataSource {
Connection getConnection() throws SQLException;
}
开源连接池(DBCP、C3P0、Druid)都实现了该接口
通过 getConnection() 获取连接
调用 close() 方法时,底层被增强为归还连接而非销毁
五、主流连接池对比
| 连接池 | 特点 |
|---|---|
| DBCP | Apache 提供,轻量级 |
| C3P0 | 支持自动回收空闲连接 |
| Druid | 阿里出品,功能最强,支持监控、SQL日志、加密 |
六、Druid 连接池实战
- 导入依赖
XML
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
2.编写测试程序
java
import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 测试连接池对象
*/
public class JdbcTest6 {
public static void main(String[] args) {
// 创建连接池对象,从连接池中获取到连接对象
DruidDataSource dataSource = new DruidDataSource();
// 设置4个参数 驱动类 地址 用户名 密码
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///jdbcdemo");
dataSource.setUsername("root");
dataSource.setPassword("root");
// 设置初始化连接个数,默认是0
dataSource.setInitialSize(5);
// 设置最大连接数
dataSource.setMaxActive(10);
// 最大等待时间,单位是毫秒 2秒
dataSource.setMaxWait(2000);
// 定义链接对象
Connection conn = null;
PreparedStatement stmt = null;
try {
// 获取到连接对象
conn = dataSource.getConnection();
// 编写SQL语句
String sql = "insert into t_user values (null,?,?,?)";
// 预编译SQL语句
stmt = conn.prepareStatement(sql);
// 设置值
stmt.setString(1,"eee");
stmt.setString(2,"eee");
stmt.setString(3,"eee");
// 执行sql
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
// 释放资源
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
// 把conn关闭了,其实连接池的底层已经对close方法进行增强。原来是销毁连接,现在是归还连接。
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
- 配置文件方式
druid.properties
XML
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbcdemo
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3
4.编写工具类
java
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* JDBC的工具类 1.0版本
* JDBC的工具类 2.0版本(智能一些),编写properties属性文件,程序就可以读取属性文件
* JDBC的工具类 3.0版本,加入连接池对象
*/
public class JdbcUtils2 {
// 连接池对象
private static DataSource DATA_SOURCE;
static{
// 加载属性文件
Properties pro = new Properties();
InputStream inputStream = JdbcUtils2.class.getResourceAsStream("/druid.properties");
try {
// 加载属性文件
pro.load(inputStream);
// 创建连接池对象
DATA_SOURCE = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从连接池中获取连接,返回。
* @return
*/
public static Connection getConnection(){
Connection conn = null;
try {
conn = DATA_SOURCE.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭资源
* @param conn
* @param stmt
* @param rs
*/
public static void close(Connection conn, Statement stmt, ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 关闭资源
* @param conn
* @param stmt
*/
public static void close(Connection conn, Statement stmt){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}