数据库连接池
①没有使用数据库连接池之前
当有多个线程,每个线程都需要连接mysql数据库,执行SQL语句,那么每一个线程都会创建一个Connection连接,当操作完毕之后也会关闭这个连接。
这样频繁的连接和关闭也是耗费时间,因此创建连接和关闭连接都是消耗资源的
②数据库连接池概念
数据库连接池负责分配、管理和释放数据库连接Connection,它允许应用程序重复使用一个现有的连接对象Connection,而不是多次创建使用。
实际开发中”获取连接“和”释放资源“是非查消耗系统资源的两个过程,为了解决性能问题,通常我们采用连接池技术,来”共享“Connection对象,那么连接对象、销毁释放资源都交给了数据库连接池。
③数据库连接池原理
连接池基本的思想就是在系统初始化的时候,将数据库连接作为对象存储到内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从数据库连接池中取出一个已经创建的连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个用户请求访问使用。
而连接的建立、断开都是由连接池来管理,同时,我们也可以进行设置连接池的初始连接数、连接的上下限个数,每个连接的最大使用次数、最大空闲时间等,也可以通过自身的管理机制来监视连接池的连接数量、使用情况等。
④常用的数据库连接池
DBCP ----> Apache下的项目
C3P0 -----> Hibernate底层就是使用C3P0连接池
Druid -----> 阿里巴巴
HikarCP -----> 速度最快的连接池,Spring框架底层
⑤Druid连接池
1、下载Druid依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
name:配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开。 如果没有配置,将会生成一个名字,格式是:"DataSource-"+System.identityHashCode(this)
jdbc:连接数据库的url,不同数据库不一样。例如: mysql :jdbc:mysql://10.20.153.104:3306/druid2 oracle :jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username:连接数据库的用户名
password:连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter
driverClassName:这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
initialSize:初始化连接个数
maxActive:最大连接数
minIdle:最小连接数
maxWait:等待时间
1、数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,
会从池中取出一个连接;如果当前池中正在使用的连接数等于maxActive,
则会等待一段时间,等待其他操作释放资源,如果这个等待时间超过了maxWait,则会报错。
如果当前正在使用的连接池没有达到maxActive,则会判断当前是否有空闲连接,如果有则使用空闲连接,
如果没有则新建立一个连接
在连接使用完毕之后,不是将其连接关闭,而是将其放入到连接池中,等待其他操作复用。
2、连接池内部有机制判断,如果当前总的连接数少于minIdle,则会建立新的空闲连接,以保证连接数得到minIdle
有些数据库连接的时候有超时限制(mysql中连接8小时之后会断开),或者由于网络中断的原因,连接池的连接会出现失效的情况。
⑥
1、最小连接数:
是连接池一直保持的数据库连接,所以如果程序对数据库连接使用量不大,将会出现大量的数据库连接资源浪费
2、最大连接数:
是连接池中能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这样也会影响到数据库的操作
3、最小和最大连接数的差距
最小连接数与最大连接数相差太大,那么最先的连接请求会获取连接,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会立马被释放,将会被放到连接池中等待其他重复使用或空闲超时后被释放。
⑦数据库连接池应用
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc_db?\
characterEncoding=utf-8&useUnicode=true&serverTimezone=Asia/Shanghai
username=root
password=123456
#使用连接池
#初始化连接个数
initialSize=10
#最小连接数
minIdle=10
#最大连接数
maxActive=20
#等待时间 单位为毫秒
maxWait=3000
package com.softeem.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* 替换DBConnection
* @author zhengwen
* @create 2022-03-08 11:10
*/
public class DruidPool {
//1.创建数据源(连接池)
private static DataSource dataSource;
//2.通过静态游离块加载
static {
try {
//3.创建一个空属性列表,使用流的方式读取配置文件
Properties p = new Properties();
InputStream is = DruidPool.class.getClassLoader()
.getResourceAsStream("druid.properties");
p.load(is);
//创建一个DataSource对象
dataSource = DruidDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return dataSource;
}
//获取连接对象
public static Connection getConn(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
/*DataSource dataSource = DruidPool.getDataSource();
System.out.println("dataSource = " + dataSource);*/
Connection conn = getConn();
System.out.println("conn = " + conn);
}
}