连接池的理解
不使用连接池有啥问题
Connection 对象是重量级对象,创建 Connection 对象就是建立两个进程之间的通信,非常耗费资源。一次完整的数据库操作,大部分时间都耗费在连接对象的创建。
第一个问题:每一次请求都创建一个 Connection 连接对象,效率非常低
第二个问题:连接对象的数量无法限制。如果连接对象的数量过高,会导致 mysql 数据库服务器崩溃。
使用连接池解决什么问题
提前创建好 N 个连接对象,将其放到一个集合中(这个集合就是一个缓存)。
用户请求时,需要连接对象直接从连接池中获取,不需要创建连接对象,因此效率较高。
另外,连接对象只能从连接池中获取,如果没有空闲的连接对象,只能等待,这样连接对象创建的数量就得到了控制。
javax.sql.DataSource
连接池有很多,不过所有的连接池都实现了 javax.sql.DataSource 接口。也就是说我们程序员在使用连接池的时候,不管使用哪家的连接池产品,只需要面向 javax.sql.DataSource 接口调用方法即可。
另外,实际上我们也可以自定义属于我们自己的连接池。只需要实现 DataSource 接口即可。
连接池的属性
对于一个基本的连接池来说,一般都包含以下几个常见的属性:
- 初始化连接数(initialSize):连接池初始化时创建的连接数。
- 最大连接数(maxActive):连接池中最大的连接数,也就是连接池所能容纳的最大连接数量,当连接池中的连接数量达到此值时,后续请求会被阻塞并等待连接池中有连接被释放后再处理。
- 最小空闲连接数量(minldle):指连接池中最小的空闲连接数,也就是即使当前没有请求,连接池中至少也要保持一定数量的空闲连接,以便应对高并发请求或突发连接请求的情况。
- 最大空闲连接数量(maxldle):指连接池中最大的空闲连接数,也就是连接池中最多允许保持的空闲连接数量。当连接池中的空闲连接数量达到了maxldle设定的值后,多余的空闲连接将会被连接池释放掉。
- 最大等待时间(maxWait):当连接池中的连接数量达到最大值时,后续请求需要等待的最大时间,如果超过这个时间,则会抛出异常。
- 连接有效性检查(testOnBorrow、testOnReturn):为了确保连接池中只有可用的连接,一些连接池会定期对连接进行有效性检查,这里的属性就是配置这些检查的选项。
- 连接的driver、url、user、password等。
以上这些属性是连接池中较为常见的一些属性,不同的连接池在实现时可能还会有其他的一些属性,不过大多数连接池都包含了以上几个属性,对于使用者来说需要根据自己的需要进行灵活配置。
常用的连接池
市面上常用的数据库连接池有许多,以下是其中几种:
- DBCP
2001年诞生,最早的连接池。
ApacheSoftwareFoundation的一个开源项目。
DBCP的设计初衷是为了满足Tomcat服务器对连接池管理的需求
-
c3p0
2004年诞生
c3p0是由SteveWaldman于2004年推出的,它是一个高性能、高可靠性、易配置的数据库连接池。c3p0能够提供连接池的容错能力、自动重连等功能,适用于高并发场景和数据量大的应用。 -
Druid
2012年诞生
Druid连接池由阿里巴巴集团开发,于2011年底开始对外公开,2012年正式发布。Druid是一个具有高性能、高可靠性、丰富功能的数据库连接池,不仅可以做连接池,还能做监控、分析和管理数据库,支持SQL防火墙、统计析、缓存和访问控制等功能。 -
HikariCP
2012年诞生
HikariCP是由BrettWooldridge于2012年创建的开源项目,它被认为是Java语言下最快的连接池之一,具有快速启动、低延迟、低资源消耗等优点。HikariCP连接池适用于高并发场景和云端应用。
很单纯的一个连接池,这个产品只做连接池应该做的,其他的不做。所以性能是极致的。相对于Druid来说,它更加轻量级。
Druid连接池在连接管理之外提供了更多的功能,例如SQL防火墙、统计分析、缓存、访问控制等,适用于在数据库访问过程中,需要进行细粒度控制的场景
HikariCP则更侧重于性能方面的优化,对各种数据库的兼容性也更好 -
BoneCP
2015年诞生
检查、SQL语句跟踪和性能分析、特定类型的连接池等特点。BoneCP连接池适用于大型应用系统和高并发的负载场景
连接池的使用
Druid 的使用
-
引入 jar 包
-
写配置文件
在类的根路径下创建一个属性资源文件:jdbc.properties
-
编写代码,从连接池中获取连接对象
-
关闭连接
调用 Connection 的 close()方法,但是这个 close() 方法并不是真正的关闭连接,只是将连接归还到连接池,让其称为空闲连接对象。这样其他线程可以继续使用该空闲连接。
HikariCP 的使用
- 引入 jar 包
-
写配置文件
-
编写代码,从连接池中获取连接对象
- 关闭连接
调用 Connection 的 close()方法,但是这个 close() 方法并不是真正的关闭连接,只是将连接归还到连接池,让其称为空闲连接对象。这样其他线程可以继续使用该空闲连接。