当前位置: 首页 > news >正文

Spring Boot项目中集成连接池及部分细节说明

连接池

  • 一,Connection连接
  • 二,数据库连接池
  • 三,集成数据库连接池
    • 1,Spring Boot默认连接池
    • 2,Druid连接池
    • 3,集成Druid(原生版本)
      • 3.1,引入依赖
      • 3.2,配置数据源
      • 3.3,编写配置文件
      • 3.4,开启Druid数据源监控
      • 3.5,测试
    • 4,集成Druid(Starter)
      • 4.1,引入依赖
      • 4.2,编写配置文件
      • 4.3,测试

为了节省数据库资源与提升运行效率,一般都会在项目中集成连接池,平时只是引入依赖,写好配置就直接用了,很多细节没有考虑过,这里做一下记录。

一,Connection连接

什么是Connection连接呢?
Connection对象是和数据库建立的通信连接对象,执行SQL的底层逻辑就要通过Connection对象实现。(讲得有点迷,不是太懂)
实际操作一下吧。
我们查到通过如下命令可以查到MySQL当前连接数量:

  • 该命令可以列出当前所有连接到MySQL的客户端,以及每个连接的详细信息,包括ID、用户、主机、数据库、命令、时间等。
mysql> SHOW PROCESSLIST;
  • 该命令将返回Threads_connected状态变量的当前值,该变量记录了已建立的当前连接数。
mysql> SHOW STATUS LIKE 'Threads_connected';

我们进入MySQL服务,执行上述的命令,下面是我本机执行的结果:
在这里插入图片描述
上面显示我本机的MySQL目前有两个连接,一个应该是我打开的这个命令行窗口的连接,另一个连接有可能是Navicat打开得,因为之前用Navicat查看过数据库。可以关掉Navicat的连接再试一次。
在这里插入图片描述
应该是了,关掉Navicat以后连接只有一个了,这样就容易理解Connection为什么是数据库连接对象了。

二,数据库连接池

上面我们知道了什么是Connection,那数据库连接池又是什么呢?
先来说说线程池Executors,我们通过Executors.newFixedThreadPool(10);可以创建一个定长的线程池,线程池里最大有10个线程,线程池创建了线程,执行完成任务后该线程不会销毁,而是放在线程池中,等待下一次任务的处理。
通过线程池,由此及彼,那数据库连接池也是预先创建一批数据库连接对象,将它们放入数据库连接池中,当有数据库操作任务时,就从连接池中取出预先创建好的连接对象来执行相应的任务。

三,集成数据库连接池

1,Spring Boot默认连接池

数据库连接池技术有: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 {@Autowiredprivate DataSource dataSource;@Testpublic 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默认使用的连接池。

2,Druid连接池

  • Druid是阿里巴巴开源的数据库连接池项目,后来贡献给了Apache开源;
  • Druid的作用是负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个;
  • Druid连接池内置强大的监控功能,其中的StatFilter功能,能采集非常完备的连接池执行信息,方便进行监控,而监控特性不影响性能;
  • Druid连接池内置了一个监控页面,提供了非常完备的监控信息,可以快速诊断系统的瓶颈。

3,集成Druid(原生版本)

Druid依赖有两个,一个是原生的依赖,另一个是再次封装的springboot-starter依赖。

3.1,引入依赖

原生依赖如下:

<!--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>

3.2,配置数据源

#设置数据库连接信息
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNullusername: rootpassword: 12345# type指定数据源类型,当前类型Druidtype: com.alibaba.druid.pool.DruidDataSource

用之前的代码测试数据源可以发现数据源已由HikariCP变为了Druid,数据源指定成功。

连接类型:class com.alibaba.druid.pool.DruidDataSource
数据库连接对象:com.mysql.cj.jdbc.ConnectionImpl@3c1908c8

3.3,编写配置文件

#设置数据库连接信息
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNullusername: rootpassword: 12345# type可以指定数据源类型type: com.alibaba.druid.pool.DruidDataSource# druid数据源相关配置# 初始化大小initialSize: 5# 最小连接数minIdle: 10# 最大连接数maxActive: 20# 获取连接时的最大等待时间maxWait: 60000# 一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 多久才进行一次检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRuns-millis: 60000#验证库是否正常sqlvalidationQuery: select 'x'#空闲时验证,防止连接断开testWhileIdle: truetestOnBorrow: falsetestOnReturn: false# 打开PSCache,并且指定每个连接上PSCache的大小poolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙filters: stat,wall,slf4j# 通过connectProperties属性来打开mergeSql功能;慢SQL记录connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

3.4,开启Druid数据源监控

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*/@Beanpublic FilterRegistrationBean webStartFilter(){FilterRegistrationBean bean = new FilterRegistrationBean();bean.setFilter(new WebStatFilter());//可以过滤的请求HashMap<String, String> initParameters = new HashMap<>();//排除一些不必要的urlinitParameters.put("exclusions","*.js,*.css,/druid/*");bean.setInitParameters(initParameters);//设置初始化参数return bean;}}

3.5,测试

  • 监控页面:http://localhost:7080/demo/druid/
    • 7080:项目端口
    • demo:上下文路径,具体看配置文件中是否有配置

刚打开页面里面没有数据,当执行了SQL后,会显示执行的SQL,以及当前数据源的配置信息。
在这里插入图片描述

  • 测试数据库连接数:
    配置文件中初始化连接数为5,可以启动项目测试一下看连接是否生效。
    项目未启动时数据库连接数:只有一个连接,是我们打开的命令行窗口
    在这里插入图片描述
  • 项目启动后:
    在这里插入图片描述
    数据库连接数变为了6个,多出来的一个是CMD窗口连接,说明配置生效。

4,集成Druid(Starter)

4.1,引入依赖

该依赖是封装后的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>

4.2,编写配置文件

#设置数据库连接信息
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNullusername: rootpassword: 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: truestat-view-servlet:# 是否开启StateViewServletenabled: true# 访问监控页面 白名单,默认127.0.0.1allow: 127.0.0.1# 访问监控页面 黑名单deny: 192.168.56.1login-username: adminlogin-password: 123456filter:stat:# 是否开启FilterStat,默认为trueenabled: true# 是否开启慢SQL记录,默认falselog-slow-sql: true# 河北多个连接池的监控数据,默认falsemerge-sql: false

引入spring-boot-starter依赖后就不需要再额外编写配置类了,上面的配置文件里可以配置监控信息

4.3,测试

启动项目,监控页面:http://localhost:7080/demo/druid/
在这里插入图片描述
查看数据库连接数也可以发现连接数已建立
在这里插入图片描述

相关文章:

  • 【开源】JAVA+Vue.js实现大学兼职教师管理系统
  • CodeFuse新开源模型荣登Big Code评测榜首!
  • MySQL原理(三)锁定机制
  • HarmonyOS 鸿蒙驱动消息机制管理
  • Python与ArcGIS系列(二十)GDAL之合并shp和geojson要素图层
  • 安装好IntelliJ IDEA点击无反应,如何解决配置文件不一致导致的启动问题
  • Linux之快速入门(CentOS 7)
  • day38_MySQL
  • 宝塔控制面板配置SSL证书实现网站HTTPS
  • ARCGIS PRO SDK 常用的选择操作
  • 前端颜料盘??
  • .net访问oracle数据库性能问题
  • 基于SSM的二手车交易网站设计与实现(有报告)。Javaee项目。ssm项目。
  • LeetCode——415. 字符串相加
  • uniapp 实现路由拦截,权限或者登录控制
  • Angular4 模板式表单用法以及验证
  • AWS实战 - 利用IAM对S3做访问控制
  • django开发-定时任务的使用
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • Joomla 2.x, 3.x useful code cheatsheet
  • Linux中的硬链接与软链接
  • Netty源码解析1-Buffer
  • Rancher-k8s加速安装文档
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Vue.js源码(2):初探List Rendering
  • 关于springcloud Gateway中的限流
  • 力扣(LeetCode)357
  • 聊聊flink的TableFactory
  • 前端攻城师
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 使用docker-compose进行多节点部署
  • 新手搭建网站的主要流程
  • Spring第一个helloWorld
  • #{}和${}的区别是什么 -- java面试
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (二)斐波那契Fabonacci函数
  • (论文阅读30/100)Convolutional Pose Machines
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • ***检测工具之RKHunter AIDE
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .Net CF下精确的计时器
  • .Net core 6.0 升8.0
  • .NET Micro Framework初体验(二)
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 事件模型教程(二)
  • .net和jar包windows服务部署