再有人问你数据库连接池 Druid 的原理,这篇文章甩给他!

【再有人问你数据库连接池 Druid 的原理,这篇文章甩给他!】SpringBoot项目中,数据库连接池已经成为标配 , 然而,我曾经遇到过不少连接池异常导致业务错误的事故 。很多经验丰富的工程师也可能不小心在这方面出现问题 。
在这篇文章中 , 我们将探讨数据库连接池,深入解析其实现机制,以便更好地理解和规避潜在的风险 。

再有人问你数据库连接池 Druid 的原理,这篇文章甩给他!

文章插图
图片
1 为什么需要连接池假如没有连接池,我们操作数据库的流程如下:
  1. 应用程序使用数据库驱动建立和数据库的 TCP 连接 ;
  2. 用户进行身份验证 ;
  3. 身份验证通过,应用进行读写数据库操作 ;
  4. 操作结束后,关闭 TCP 连接。
创建数据库连接是一个比较昂贵的操作,若同时有几百人甚至几千人在线,频繁地进行连接操作将占用更多的系统资源,但数据库支持的连接数是有限的,创建大量的连接可能会导致数据库僵死 。
当我们有了连接池,应用程序启动时就预先建立多个数据库连接对象,然后将连接对象保存到连接池中 。当客户请求到来时,从池中取出一个连接对象为客户服务 。当请求完成时,客户程序调用关闭方法 , 将连接对象放回池中 。
再有人问你数据库连接池 Druid 的原理,这篇文章甩给他!

文章插图
图片
相比之下,连接池的优点显而易见:
1、资源重用:
因为数据库连接可以重用,避免了频繁创建,释放连接引起的大量性能开销 , 同时也增加了系统运行环境的平稳性 。
2、提高性能
当业务请求时,因为数据库连接在初始化时已经被创建,可以立即使用,而不需要等待连接的建立,减少了响应时间 。
3、优化资源分配
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源 。
4、连接管理
数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露 。
2 JDBC 连接池下面的代码展示了 JDBC 操作数据库的流程 :
//1. 连接到数据库Connection connection = DriverManager.getConnection(jdbcUrl, username, password);//2. 执行SQL查询String sqlQuery = "SELECT * FROM mytable WHERE column1 = ?";PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery);preparedStatement.setString(1, "somevalue");resultSet = preparedStatement.executeQuery();//3. 处理查询结果while (resultSet.next()) {int column1Value = https://www.isolves.com/it/sjk/bk/2023-12-11/resultSet.getInt("column1");String column2Value = resultSet.getString("column2");System.out.println("Column1: " + column1Value + ", Column2: " + column2Value);}//4. 关闭资源resultSet.close();preparedStatement.close();connection.close();上面的方式会频繁的创建数据库连接 , 在比较久远的 JSP 页面中会偶尔使用 , 现在普遍使用 JDBC 连接池 。
JDBC 连接池有一个标准的数据源接口JAVAx.sql.DataSource,这个类位于 Java 标准库中 。
public interface DataSourceextends CommonDataSource, WrApper {Connection getConnection() throws SQLException;Connection getConnection(String username, String password) throws SQLException;}常用的 JDBC 连接池有:
  • HikariCP
  • C3P0
  • Druid
Druid(阿里巴巴数据库连接池)是一个开源的数据库连接池库,它提供了强大的数据库连接池管理和监控功能 。
1)配置Druid数据源
DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl("jdbc:MySQL://localhost:3306/mydatabase");dataSource.setUsername("yourusername");dataSource.setPassword("yourpassword");dataSource.setInitialSize(5); // 初始连接池大小dataSource.setMinIdle(5); // 最小空闲连接数dataSource.setMaxActive(20); // 最大活动连接数dataSource.setValidationQuery("select 1 from dual");// 心跳的 QuerydataSource.setMaxWAIt(60000); // 最大等待时间dataSource.setTestOnBorrow(true); // 验证连接是否有效2)使用数据库连接
Connection connection = dataSource.getConnection();//使用连接执行数据库操作// TODO 业务操作// 使用后关闭连接连接connection.close();


推荐阅读