赞
踩
为了节省数据库资源与提升运行效率,一般都会在项目中集成连接池,平时只是引入依赖,写好配置就直接用了,很多细节没有考虑过,这里做一下记录。
什么是Connection连接呢?
Connection对象是和数据库建立的通信连接对象,执行SQL的底层逻辑就要通过Connection对象实现。(讲得有点迷,不是太懂)
实际操作一下吧。
我们查到通过如下命令可以查到MySQL当前连接数量:
mysql> SHOW PROCESSLIST;
mysql> SHOW STATUS LIKE 'Threads_connected';
我们进入MySQL服务,执行上述的命令,下面是我本机执行的结果:

上面显示我本机的MySQL目前有两个连接,一个应该是我打开的这个命令行窗口的连接,另一个连接有可能是Navicat打开得,因为之前用Navicat查看过数据库。可以关掉Navicat的连接再试一次。

应该是了,关掉Navicat以后连接只有一个了,这样就容易理解Connection为什么是数据库连接对象了。
上面我们知道了什么是Connection,那数据库连接池又是什么呢?
先来说说线程池Executors,我们通过Executors.newFixedThreadPool(10);可以创建一个定长的线程池,线程池里最大有10个线程,线程池创建了线程,执行完成任务后该线程不会销毁,而是放在线程池中,等待下一次任务的处理。
通过线程池,由此及彼,那数据库连接池也是预先创建一批数据库连接对象,将它们放入数据库连接池中,当有数据库操作任务时,就从连接池中取出预先创建好的连接对象来执行相应的任务。
数据库连接池技术有:DBCP、tomcat-jdbc、C3P0、HikariCP、Druid等。
若没有引入额外的连接池,Spring Boot 2.x默认使用HikariCP作为项目的数据库连接池。
可以通过下面的代码测试当前项目的连接池:(Spring Boot版本:2.5.0)
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @SpringBootTest public class DataSourceTest { @Autowired private DataSource dataSource; @Test public void testDataSource() { System.out.println("连接类型:" + dataSource.getClass()); try { // 获得数据库连接 Connection connection = dataSource.getConnection(); System.out.println("数据库连接对象:" + connection); // 关闭连接 connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }
连接类型:class com.zaxxer.hikari.HikariDataSource
数据库连接对象:HikariProxyConnection@991572261 wrapping com.mysql.cj.jdbc.ConnectionImpl@4199761d
可以发现Spring Boot默认集成的数据库连接池是HikariCP。HikariCP有着很高的性能和并发性,是SpringBoot默认使用的连接池。
Druid依赖有两个,一个是原生的依赖,另一个是再次封装的springboot-starter依赖。
原生依赖如下:
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.4</version>
</dependency>
除Druid外,还需引入下面的依赖
<!--各依赖版本需根据SpringBoot确定,当前项目SpringBoot:2.5.0--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <version>2.5.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency>
#设置数据库连接信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
username: root
password: 12345
# type指定数据源类型,当前类型Druid
type: com.alibaba.druid.pool.DruidDataSource
用之前的代码测试数据源可以发现数据源已由HikariCP变为了Druid,数据源指定成功。
连接类型:class com.alibaba.druid.pool.DruidDataSource
数据库连接对象:com.mysql.cj.jdbc.ConnectionImpl@3c1908c8
#设置数据库连接信息 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull username: root password: 12345 # type可以指定数据源类型 type: com.alibaba.druid.pool.DruidDataSource # druid数据源相关配置 # 初始化大小 initialSize: 5 # 最小连接数 minIdle: 10 # 最大连接数 maxActive: 20 # 获取连接时的最大等待时间 maxWait: 60000 # 一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRuns-millis: 60000 #验证库是否正常sql validationQuery: select 'x' #空闲时验证,防止连接断开 testWhileIdle: true testOnBorrow: false testOnReturn: false # 打开PSCache,并且指定每个连接上PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
Druid数据源具有监控的功能,并提供了一个web界面方便用户查看。以下配置文件中配置了Druid监控后台的Servlet,以及Web和Druid数据源之间的管理关联监控统计。
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.util.HashMap; /** * @author zhhao * @date 2024-01-30 12:02 * @describe */ @Configuration public class DruidConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource")//和配置文件绑定 public DataSource druidDataSource(){ return new DruidDataSource(); } //获取后台监控 @Bean //由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件。 // 所以想用使用Servlet功能,就必须要借用SpringBoot提供的ServletRegistrationBean接口。 public ServletRegistrationBean servletRegistration(){ ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*"); //StatViewServlet用于展示Druid的统计信息 //设置后台登录的账户和密码 HashMap<String, String> initParameters = new HashMap<>(); // IP白名单 initParameters.put("allow",""); // IP黑名单(共同存在时,deny优先于allow) initParameters.put("deny",""); //增加配置 登录的key是固定的 initParameters.put("loginUsername","admin"); initParameters.put("loginPassword","123456"); //设置谁可以访问 initParameters.put("allow","");//任何人都可以访问 //设置初始化参数 bean.setInitParameters(initParameters); return bean; } /** * 用于配置Web和Druid数据源之间的管理关联监控统计 * @return */ @Bean public FilterRegistrationBean webStartFilter(){ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new WebStatFilter()); //可以过滤的请求 HashMap<String, String> initParameters = new HashMap<>(); //排除一些不必要的url initParameters.put("exclusions","*.js,*.css,/druid/*"); bean.setInitParameters(initParameters);//设置初始化参数 return bean; } }
刚打开页面里面没有数据,当执行了SQL后,会显示执行的SQL,以及当前数据源的配置信息。



该依赖是封装后的springboot-starter依赖,可以更方便的集成到Spring Boot项目中。
Github:druid-spring-boot-starter
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
#设置数据库连接信息 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull username: root password: 12345 # type可以指定数据源类型 type: com.alibaba.druid.pool.DruidDataSource # druid数据源相关配置 druid: # 初始化大小 initial-size: 5 # 最小连接数 min-idle: 5 # 最大连接数 max-active: 20 # 获取连接时的最大等待时间 max-wait: 60000 # 一个连接在池中最小生存的时间,单位是毫秒 min-evictable-idle-time-millis: 300000 # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒 time-between-eviction-runs-millis: 60000 # 检测连接是否有效的sql语句,为空时以下三个配置均无效 validation-query: select 1 # 申请连接时执行validationQuery检测连接是否有效,默认true,开启后会降低性能 test-on-borrow: true # 归还连接时执行validationQuery检测连接是否有效,默认false,开启后会降低性能 test-on-return: true # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认false,建议开启,不影响性能 test-while-idle: true stat-view-servlet: # 是否开启StateViewServlet enabled: true # 访问监控页面 白名单,默认127.0.0.1 allow: 127.0.0.1 # 访问监控页面 黑名单 deny: 192.168.56.1 login-username: admin login-password: 123456 filter: stat: # 是否开启FilterStat,默认为true enabled: true # 是否开启慢SQL记录,默认false log-slow-sql: true # 河北多个连接池的监控数据,默认false merge-sql: false
引入spring-boot-starter依赖后就不需要再额外编写配置类了,上面的配置文件里可以配置监控信息
启动项目,监控页面:http://localhost:7080/demo/druid/

查看数据库连接数也可以发现连接数已建立

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。