JDBC强化关键_009_连接池
目 录
一、概述
1.未使用连接池带来的问题
2.连接池解决的问题
3.所有连接池都实现的接口
4.连接池的常见属性
二、常用连接池
三、Bruid 连接池
1.引入 druid 的 jar 包
2.配置文件
3.从连接池获取连接对象
4.利用 Bruid 连接池改造工具类
四、HikariCP 连接池
1.引入 HikariCP 的 jar 包
2.配置文件
3.从连接池获取连接对象
一、概述
1.未使用连接池带来的问题
- Connection 是重量级对象,创建 Connection 对象就是建立两个进程间的通信,非常耗费资源。一次完整的数据库操作,大部分时间耗费在连接对象的创建;
- 每一次请求都创建一个 Connection 对象,效率较低;
- 连接对象的数量无法限制,若数量过高,会导致数据库服务器崩溃。
2.连接池解决的问题
- 事先创建好多个连接对象,放入集合中;
- 用户请求时,需要连接对象直接从连接池中获取,无需创建连接对象,效率较高;
- 连接对象只能从连接池中获取,若没有空闲的连接对象就只能等待,如此便控制了创建连接对象的数量。
3.所有连接池都实现的接口
- 连接池有很多种,但它们都实现了 javax.sql.DataSource 接口;
- 可以自定义连接池,只需实现 DataSource 接口。
4.连接池的常见属性
- 初始化连接数(initialSize):连接池初始化时创建的连接数;
- 最大连接数(maxActive):连接池中的最大连接数。当连接池中的连接数量达到此值时,后续请求会被阻塞并等待连接池中有连接被释放后再处理;
- 最小空闲连接数(minIdle):连接池中最小空闲连接数。即当下没有请求,但连接池中至少也要保持一定数量的空闲连接,以便应对高并发请求或突发连接请求;
- 最大空闲连接数(maxIdle):连接池中最大空闲连接数。即连接池中空闲连接数量达到设定值后,多余的空闲连接将会被连接池释放掉;
- 最大等待时间(maxWait):连接池中连接数量达到最大值时,后续请求需要等待的最大时间。若超出该时间,就会抛出异常;
- 连接有效性检查:为确保连接池中只有可用连接,一些连接池会定期对连接进行有效性检查。testOnBorrow、testOnReturn 属性就是配置检查的选项;、
- driver、url、user、password 等。
二、常用连接池
DBCP:2001年诞生,最早的连接池。是 Apache Software Foundation 的一个开源项目。设计初衷是为了满足 Tomcat 服务器对连接池管理的需求;
c3p0:由 Steve Waldman 于 2004 年推出的,是一个高性能、高可靠性、易配置的数据库连接池。能够提供连接池的容错能力、自动重连等功能,适用于高并发场景和数据量大的应用;
Druid:阿里巴巴集团开发,2011 年底开始对外公开,2012 年正式发布。Druid 是一个具有高性能、高可靠性、丰富功能的数据库连接池,不仅可以做连接池,还能做监控、分析和管理数据库,支持SQL防火墙、统计分析、缓存和访问控制等功能;
HikariCP:Brett Wooldridge 于2012年创建的开源项目,被认为是 Java 语言下最快的连接池之一,具有快速启动、低延迟、低资源消耗等优点。HikariCP 连接池适用于高并发场景和云端应用。性能是极致的,相对于 Druid 来说,它更加轻量级。Druid 连接池在连接管理之外提供了更多的功能,例如 SQL 防火墙、统计分析、缓存、访问控制等,适用于在数据库访问过程中,需要进行细粒度控制的场景。HikariCP 则更侧重于性能方面的优化,对各种数据库的兼容性也更好;
BoneCP:一款 Java 语言下的高性能连接池,于 2015 年由 Dominik Gruntz 在 GitHub 上发布。BoneCP 具有分布式事务、连接空闲检查、SQL 语句跟踪和性能分析、特定类型的连接池等特点。BoneCP 连接池适用于大型应用系统和高并发的负载场景。
三、Bruid 连接池
1.引入 druid 的 jar 包
2.配置文件
# 根路径下创建 jdbc.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=root
initialSize=5
minIdle=10
maxActive=20
3.从连接池获取连接对象
public class DruidTest {public static void main(String[] args) throws Exception {// 获取一个输入流,指向一个属性资源文件InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");// 创建属性类对象Properties properties = new Properties();// 将属性资源文件加载到属性类对象中properties.load(in);// 获取连接池对象DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);// 通过连接池获取连接对象Connection connection = dataSource.getConnection();System.out.println(connection);// CRUD 操作// 关闭资源,不是真正关闭,只是将连接池中的连接对象状态修改为空闲connection.close();}
}
4.利用 Bruid 连接池改造工具类
public class DbUtils2 {// 工具类的构造方法都是私有的,不能被实例化。private DbUtils2() {}private static DataSource dataSource;static {try {// 获取一个输入流,指向一个属性资源文件InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");// 创建属性类对象Properties properties = new Properties();// 将属性资源文件加载到属性类对象中properties.load(in);// 获取连接池对象dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}public static void close(Connection connection, Statement statement, ResultSet resultSet) {if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
public class ConnectionTest {public static void main(String[] args) throws SQLException {Connection c1 = DbUtils2.getConnection();Connection c2 = DbUtils2.getConnection();Connection c3 = DbUtils2.getConnection();Connection c4 = DbUtils2.getConnection();Connection c5 = DbUtils2.getConnection();System.out.println(c1);System.out.println(c2);System.out.println(c3);System.out.println(c4);System.out.println(c5);}
}
四、HikariCP 连接池
1.引入 HikariCP、slf4j-api jar 包
2.配置文件
# 根路径下创建 jdbc2.properties
driverClassName=com.mysql.cj.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/jdbc
username=root
password=root
minimumIdle=5
maximumPoolSize=20
3.从连接池获取连接对象
public class HikariCPTest {public static void main(String[] args) throws Exception {// 获取一个输入流,指向属性资源文件InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc2.properties");// 创建属性类对象Properties properties = new Properties();// 将属性资源文件加载到属性类对象中properties.load(in);// 创建配置信息对象HikariConfig config = new HikariConfig(properties);// 获取连接池对象DataSource dataSource = new HikariDataSource(config);// 通过连接池获取连接对象Connection connection = dataSource.getConnection();System.out.println(connection);// CRUD 操作// 释放连接对象connection.close();}
}