一、为什么需要连接池?
在传统的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接口,所有连接池都必须实现它:
public interface DataSource { Connection getConnection() throws SQLException; }开源连接池(DBCP、C3P0、Druid)都实现了该接口
通过getConnection()获取连接
调用close()方法时,底层被增强为归还连接而非销毁
五、主流连接池对比
| 连接池 | 特点 |
|---|---|
| DBCP | Apache 提供,轻量级 |
| C3P0 | 支持自动回收空闲连接 |
| Druid | 阿里出品,功能最强,支持监控、SQL日志、加密 |
六、Druid 连接池实战
1. 导入依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>2.编写测试程序
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(); } } } } }3. 配置文件方式
druid.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///jdbcdemo username=root password=root initialSize=5 maxActive=10 maxWait=3000 maxIdle=6 minIdle=34.编写工具类
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(); } } } }