自学内容网 自学内容网

SpringBoot3集成Druid数据库连接池

一,了解Druid连接池

1,什么是Druid连接池

       Druid是一个开源的数据库连接池,旨在为Java应用程序提供高性能、可扩展、易于管理的数据库连接服务。Druid通过优化数据库连接的使用方式,可以显著提高应用程序的性能和响应速度。其次,Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。

2,Druid和Springboot默认连接池HikariCP对比

版本对比

HikariCP的版本较为多样,覆盖了不同的数据库和JDK版本。而Druid的版本则相对较少,但仍然支持多种数据库和JDK。在选择时,请确保您所使用的数据库和JDK版本与所选连接池版本兼容。

性能对比

在性能方面,两者都是很好的选择,但在大多数情况下,HikariCP的性能优于Druid。

HikariCP的优点如下:

1、快速启动,在启动时不需要初始化多余资源。

2、高效的对象封装:对象的封装采用了更少的内存,不会初始化多余资源,操作效率更高。

3、线程安全:线程调度的时候,不会受到阻塞的影响,增加了并发使用的效率。

Druid的优点如下:

1、大而全的功能:Druid支持的功能非常丰富,包括监控、SQL防火墙、SQL解析、SQL执行分析等等。

2、易于管理:Druid提供了非常详细的接口,可以帮助管理员实时监控系统状态,并提供了详细的日志。

3、使用方便:Druid的数据源扩展了JDBC的DataSource接口,通过简单配置即可实现数据库连接池的使用。

易用性对比

HikariCP提供了简洁的API和丰富的配置选项,使得配置和使用变得相对简单。而Druid的配置相对较为复杂,但提供了更多的监控和管理功能。在使用上,HikariCP可能更适合对性能和简洁性有较高要求的开发人员,而Druid可能更适合需要更强大监控和扩展功能的开发人员。

       综上所述,HikariCP和Druid各有优劣,需要根据实际需求进行选择。如果需要频繁创建和关闭连接,对性能要求较高,可以选择HikariCP;如果需要长时间保持连接,对稳定性和监控功能要求较高,可以选择Druid。无论选择哪种数据库连接池,都需要对其进行充分的测试和监控,以确保其性能和稳定性满足应用程序的需求。同时,还需要关注其版本兼容性和易用性,以便在开发和维护过程中获得更好的体验。

3,Druid配置项说明
配置项名称缺省值说明
nameDataSource-****配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。如果没有配置,将会生成一个名字,格式是:"DataSource-" + System.identityHashCode(this)
url连接数据库的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根据url自动识别这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
initialSize0初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive8最大连接池数量
minIdle0连接池最小空闲数量
maxWait-1获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatementsfalse是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。

maxOpenPreparedStatements  

10要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
maxPoolPreparedStatementPerConnectionSize10要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuerynull用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
validationQueryTimeout-1单位:秒,检测连接是否有效的超时时间,大于0才生效。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法
testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturnfalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis60000有两个含义:
1) Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun3不再使用,已经彻底废弃,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis1800000连接保持空闲而不被驱逐的最小时间
connectionInitSqls[]数组方式定义物理连接初始化的时候执行的1到多条sql语句,比如连接MySQL数据库使用低版本驱动的情况下,想使用utf8mb4,则可以配置sql为: set NAMES 'utf8mb4'
exceptionSorter根据dbType自动识别当数据库抛出一些不可恢复的异常时,抛弃连接
filters属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 
监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall
proxyFilters类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

二,SpringBoot3集成Druid

1,引入依赖

版本要和Springboot3兼容

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-3-starter</artifactId>
    <version>1.38.0</version>
</dependency>
<!-- 如果你使用的是 Spring Boot 2.x 或更早版本,那么您应该使用 javax.servlet-api 而不是 jakarta.servlet-api -->
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version>
</dependency>
2,修改配置文件
spring:
  datasource: # mysql 数据源配置
    type: com.alibaba.druid.pool.DruidDataSource # 配置连接池类型为 druid
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/druid?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: root
    druid:
      # 初始化时建立物理连接的个数
      initial-size: 5
      # 连接池的最小空闲数量
      min-idle: 5
      # 连接池最大连接数量
      max-active: 20
      # 获取连接时最大等待时间,单位毫秒
      max-wait: 60000
      # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
      test-while-idle: true
      # 既作为检测的间隔时间又作为testWhileIdel执行的依据
      time-between-eviction-runs-millis: 60000
      # 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接(配置连接在池中的最小生存时间)
      min-evictable-idle-time-millis: 30000
      # 用来检测数据库连接是否有效的sql 必须是一个查询语句(oracle中为 select 1 from dual)
      validation-query: select 1
      # 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
      test-on-borrow: false
      # 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
      test-on-return: false
      # 是否缓存preparedStatement, 也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
      pool-prepared-statements: false
      # 置监控统计拦截的filters,去掉后监控界面sql无法统计,stat: 监控统计、Slf4j:日志记录、waLL: 防御sqL注入
      filters: stat,wall,slf4j
      # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
      max-pool-prepared-statement-per-connection-size: -1
      # 合并多个DruidDataSource的监控数据
      use-global-data-source-stat: true

      web-stat-filter: # 监控web
        enabled: true
        # 添加过滤规则
        url-pattern: /*
        # 忽略过滤的格式
        exclusions: /druid/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico

      stat-view-servlet: # 配置监控页面
        enabled: true
        # 访问路径为/druid
        url-pattern: /druid/*
        # 是否能够重置数据
        reset-enable: false
        # 设置账号密码,默认为root
        login-username: admin
        login-password: admin
        # IP白名单
        allow: 127.0.0.1
        # IP黑名单(共同存在时,deny优先于allow)
        deny:
3,启动项目

出现如下日志表示使用druid连接池成功

4,访问监控页面

http://127.0.0.1:9090/druid

输入账号和密码

5,去除druid监控页面底部广告

编写配置类-DruidAdvertisingConfig,如果报错,可以将导入的类删了重新导入试试

package com.cms.config.druid;


import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure;
import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import jakarta.servlet.*;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * @author Hva
 */
@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true", matchIfMissing = true)
public class DruidAdvertisingConfig {
    /**
     * @Description: 除去页面底部的广告
     */
    @Bean
    public FilterRegistrationBean removeDruidAdFilterRegistrationBean(DruidStatProperties properties) {

        // 获取监控页面参数
        DruidStatProperties.StatViewServlet druidConfig = properties.getStatViewServlet();
        // 获取common.js位置
        String pattern = druidConfig.getUrlPattern() != null ? druidConfig.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
        final String filePath = "support/http/resources/js/common.js";

        // 利用Filter进行过滤
        Filter filter = new Filter() {
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {
            }
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                chain.doFilter(request, response);
                // 重置缓冲区,响应头不会重置
                response.resetBuffer();
                // 获取common文件内容
                String text = Utils.readFromResource(filePath);

                // 利用正则表达式删除<footer class="footer">中的<a>标签
                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
                text = text.replaceAll("powered.*?shrek.wang</a>", "");
                // 去掉头部的菜单连接
                text+="var t =null; $(function(){ t=setInterval(function(){$(\"a.brand\").hide()}, 10 ); setTimeout(function(){clearInterval(t)}, 2000 );})";
                response.getWriter().write(text);
            }
        };
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}
6,重新项目,访问druid

可以发现头部链接和底部广告都没有了


原文地址:https://blog.csdn.net/qq_62398643/article/details/142767932

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!