Spring Boot 2.x 自定义数据源 DruidDataSource(操作 mysql 数据库)「建议收藏」

2022-06-28 16:30:11 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

目录

Druid 数据源概述

切换 Druid 数据源

自定义 Druid 数据源参数

配置 Druid 数据源监控

Spring 监控

去除页脚广告

API 获取 Druid 监控数据


Druid 数据源概述

1、Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP、PROXOOL 等 DB 池的优点,同时加入了日志监控

2、Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池

3、《Spring Boot 默认数据源 HikariDataSource 与 JdbcTemplate》中已经介绍 Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源

4、本文重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。

切换 Druid 数据源

引入 Druid 数据源

1、第一步需要在应用的 pom.xml 文件中添加上 Druid 数据源依赖,可以从 Maven 仓库官网 Maven Repository 中获取.

代码语言:javascript复制
        <!-- Druid 数据源依赖,集成了 Spring boot ,方便配置 druid 属性 -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

        <!-- Mysql 数据库驱动,spring boot 2.1.3 时,mysql 驱动版本为 8.0.15 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 引入 Spring Data JPA,JPA 组件内部会依赖 JDBC 组件,JDBC 组件内部默认依赖的是 HikariCP 数据源-->
        <!--切换 druid 数据源时,HikariCP 依赖可以移除掉,不移除时也不影响-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!--引用 log4j2 spring boot 启动器,内部依赖了 slf4j、log4j;排除项目中的 logback-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

pom.xml · 汪少棠/red-door – Gitee.com

切换 Druid 数据源

1、《Spring Boot 默认数据源 HikariDataSource 与 JdbcTemplate》中已经说过 Spring Boot 2.0 以上默认使用 com.zaxxer.hikari.HikariDataSource 数据源。

2、但可以 通过 spring.datasource.type 指定数据源,可以从 Spring Boot 官方文档 查看:

代码语言:javascript复制
spring:
  datasource:
    #jdbc 基本通用配置
    username: root
    password: root
    #高版本的 spring boot 搭配的 mysql 驱动版本通常也较高,如 mysql-connector-java:8.0.X
    #此时 url 的值要带时区 serverTimezone、driver-class-name 的值要带 cj
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    #切换 Druid 数据源
    type: com.alibaba.druid.pool.DruidDataSource

src/main/resources/application.yml · 汪少棠/red-door – Gitee.com

Druid 数据源测试

1、数据源切换之后,同理可以注入 DataSource,然后获取到它,输出一看便知是否成功切换:

代码语言:javascript复制
import com.alibaba.druid.pool.DruidDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
//数据源测试,测试 spring.datasource.xx 的 druid 属性配置是否正常,数据库是否能连接上等等
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTest {
    //Spring Boot 默认已经配置好了数据源,程序员可以直接 DI 注入然后使用即可
    @Resource
    private DataSource dataSource;

    @Test
    public void contextLoads() throws SQLException {
        System.out.println("数据源>>>>>>"   dataSource.getClass());
        Connection connection = dataSource.getConnection();
        System.out.println("连接>>>>>>>>>"   connection);
        System.out.println("连接地址>>>>>"   connection.getMetaData().getURL());

        if (dataSource instanceof DruidDataSource) {
            DruidDataSource druidDataSource = (DruidDataSource) dataSource;
            System.out.println("druidDataSource 数据源最大连接数:"   druidDataSource.getMaxActive());
            System.out.println("druidDataSource 数据源初始化连接数:"   druidDataSource.getInitialSize());
            System.out.println("version="   druidDataSource.getVersion());
            System.out.println("name="   druidDataSource.getName());
        }
        connection.close();
    }

    // 控制台输出默认数据源:
    // 数据源>>>>>>class com.zaxxer.hikari.HikariDataSource
    // 连接>>>>>>>>>HikariProxyConnection@519751097 wrapping com.mysql.cj.jdbc.ConnectionImpl@11a3a45f
    // 连接地址>>>>>jdbc:mysql://127.0.0.1:3306/wang?characterEncoding=UTF-8&serverTimezone=UTC

    // 控制台输出 druid 数据源:
    // 数据源>>>>>>class com.alibaba.druid.pool.DruidDataSource
    // 连接>>>>>>>>>com.mysql.cj.jdbc.ConnectionImpl@6fc1a8f6
    // 连接地址>>>>>jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&serverTimezone=UTC
    // druidDataSource 数据源最大连接数:200
    // druidDataSource 数据源初始化连接数:10
    // version=1.2.8
    // name=druid-db1
}

src/test/java/com/wmx/reddoor/DataSourceTest.java · 汪少棠/red-door – Gitee.com

自定义 Druid 数据源参数

1、Druid 数据源参数配置在全局配置文件中即可,如下所示:

配置

说明

jdbcUrl (多数据源时使用,单数据源时使用通用的 spring.datasource.url即可)

连接数据库的url,不同数据库不一样。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto

username

连接数据库的用户名 (多数据源时使用,单数据源时使用通用的 spring.datasource.username即可)

password (多数据源时使用,单数据源时使用通用的 spring.datasource.password即可)

连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/使用ConfigFilter

driverClassName

这一项可配可不配,不配置时druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下) (多数据源时使用,单数据源时使用通用的 spring.datasource.driver-class-name即可)

connectionInitSqls

物理连接初始化的时候执行的sql

exceptionSorter

当数据库抛出一些不可恢复的异常时,抛弃连接

filters

属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall

proxyFilters

类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

代码语言:javascript复制
spring:
  datasource:
    #jdbc 通用配置,对应的是 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 中的属性
    username: root
    password: root
    #高版本的 spring boot 搭配的 mysql 驱动版本通常也较高,如 mysql-connector-java:8.0.X
    #此时 url 的值要带时区 serverTimezone、driver-class-name 的值要带 cj
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    #切换 Druid 数据源
    type: com.alibaba.druid.pool.DruidDataSource

    #druid 数据源专有配置,对应的是 com.alibaba.druid.pool.DruidDataSource 中的属性
    druid:
      #数据源名称:当存在多个数据源时,设置名字可以很方便的来进行区分,默认自动生成名称,格式是:"DataSource-"   System.identityHashCode(this)
      name: druid-db1
      initialSize: 10 #初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时,默认0
      maxActive: 200  #最大连接池数量,默认8
      minIdle: 10     #最小连接池数量
      maxWait: 60000  #获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
      timeBetweenEvictionRunsMillis: 60000 #1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据(详细看testWhileIdle属性的说明)
      minEvictableIdleTimeMillis: 300000   #设置连接最小可收回空闲时间(毫秒),默认为 1000L * 60L * 30L
      maxEvictableIdleTimeMillis: 900000   #设置连接最大可收回空闲时间(毫秒),默认为 1000L * 60L * 60L * 7
      validationQuery: SELECT 1 FROM DUAL #用来检测连接是否有效的sql,求是一个查询语句。默认为null,此时testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
      testWhileIdle: true #申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认为true
      testOnBorrow: false #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能,默认false.
      testOnReturn: false #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能,默认false.
      poolPreparedStatements: true #是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
      #要启用PSCache,必须配置大于0,当大于0时, poolPreparedStatements自动触发修改为true,
      #在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
      maxOpenPreparedStatements: 20
      #连接池中的 minIdle 数量以内的连接,空闲时间超过 minEvictableIdleTimeMillis,则会执行 keepAlive 操作
      keepAlive: true
      maxPoolPreparedStatementPerConnectionSize: 20 #每个连接大小的最大池准备语句数
      useGlobalDataSourceStat: true #是否使用全局数据源统计,默认false
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 #连接属性
      #配置监控统计的内置过滤器:stat-监控统计(必须配置,否则监控不到sql)、wall-防御sql注入、log4j2-日志记录框架(值与应用中的日志框架保持一致,如 log4j、log4j、logback、slf4j)
      filters: stat,wall,log4j2

src/main/resources/application.yml · 汪少棠/red-door – Gitee.com

2、现在可以重新测试 Druid 数据源,查看配置文件中的参数是否已经生效,也可以直接 Debug 查看 DruidDataSource 的属性。

配置 Druid 数据源监控

1、可以通过 spring.datasource.druid.filters=stat,wall,log4j2 …的方式来启用相应的内置 Filter,这些内置 Filter 使用的是默认配置。如果默认配置无法满足需求,则可以自定义 Filter,要想使自定义的 Filter 配置生效,则需要将对应 Filter 的 enabled 设置为 true。

代码语言:javascript复制
spring:
  datasource:
    #druid 数据源专有配置,对应的是 com.alibaba.druid.pool.DruidDataSource 中的属性
    druid:
      ########## 过滤器 ##########
      #配置监控统计的内置过滤器:stat-监控统计(必须配置,否则监控不到sql)、wall-防御sql注入、log4j2-日志记录框架(值与应用中的日志框架保持一致,如 log4j、log4j、slf4j等等)
      filters: stat,wall,log4j2
      #自定义过滤器配置:stat、slf4j、log4j、log4j2、commons-log、wall
      #内置Filter都是默认配置,无法满足需求时,则可以自定义 Filter,自定义的过滤器默认都是没有开启的。
      filter:
        stat: #状态监控过滤器
          enabled: true
          db-type: mysql
          log-slow-sql: true  #开启慢sql监控,超过指定时间则认为是慢sql,记录到日志中
          slow-sql-millis: 5000
        slf4j: #日志监控过滤器,使用slf4j 进行日志输出
          enabled: true
          statement-log-error-enabled: true
          statement-create-after-log-enabled: false
          statement-close-after-log-enabled: false
          result-set-open-after-log-enabled: false
          result-set-close-after-log-enabled: false
        wall: #防火墙过滤器
          enabled: true
          config:
            delete-allow: false     #不允许删除数据
            drop-table-allow: false #不允许删除表

      ########## WebStatFilter:web 状态监控过滤器 ##########
      web-stat-filter:
        enabled: true
        url-pattern: /*                 #过滤所有url
        exclusions: "*.js,*.css,*.gif,*.jpg,*.png,*.ico,/druid/*"   # 排除一些不必要的url
        session-stat-enable: true       #开启session统计功能
        session-stat-max-count: 1000    #session的最大个数,默认100

      ########## StatViewServlet(监控页面路径配置),用于展示Druid的监控统计信息 ##########
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*           #访问内置监控页面的路径,内置监控页面的首页是 http://127.0.0.1:8080/druid/login.html 或者 /druid/index.html
        reset-enable: false             #不允许清空统计数据,重新计算
        login-username: root            #配置监控页面登陆用户
        login-password: 123456          #配置监控页面登陆密码
        allow: 127.0.0.1                #允许访问的地址,如果没有配置或者为空,则允许所有访问
        deny:                           #拒绝访问的地址,deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝

2、WebStatFilter 过滤器用于统计 web 应用请求中所有的数据库信息,比如发出的 sql 语句,sql 执行的时间、请求次数、请求的 url 地址、以及seesion 监控、数据库表的访问次数 等等。

3、StatViewServlet(监控页面路径配置),用于配置 Druid 监控统计页面的登陆地址以及账号密码等信息。

4、启动应用即可访问监控页面首页: http://127.0.0.1:8080/druid/login.html 或者 /druid/index.html

Spring 监控

1、Spring 监控是用于通过 aop 切面对指定类及方法进行监控,首先应用需要引入 Aop 依赖。

代码语言:javascript复制
<!--SpringBoot 的aop 模块-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、然后配置 Spring 监控 AOP 切入点,配置多个时用英文逗号分隔。切入点表达式语法。

com.wmx..*.controller..*.*:表示 com.wmx 包任意子孙包下面的 controller 包下面任意子孙包中任意类中的任意方法。

代码语言:javascript复制
spring:
  datasource:
    druid:
      aop-patterns: com.wmx..*.controller..*.* #Spring监控AOP切入点,多个时用英文逗号分隔

去除页脚广告

1、访问监控页面的时候,页面底部(footer)会看到内置的广告,是因为引入的 druid-x.y.z.jar 包中的 common.js 中添加的广告。

2、直接到本地仓库中,找到 druid-x.y.z.jar 包,然后用压缩工具打开,找到 support/http/resources/js/common.js,然后注释掉里面的 this.buildFooter(); 或者修改为自己的页脚内容。

API 获取 Druid 监控数据

1、Druid 的监控数据不仅可以在页面上查看,在 开启 StatFilter 后,也可以通过 DruidStatManagerFacade 进行获取;

2、DruidStatManagerFacade.getDataSourceStatDataList 方法可以获取所有数据源的监控数据,

除此之外 DruidStatManagerFacade 还提供了一些其他方法,可以按需选择使用。

代码语言:javascript复制
import com.alibaba.druid.stat.DruidStatManagerFacade;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;

//druid 数据源监控信息
@RestController
public class DruidController {

    /**获取 druid 数据监控信息
     * http://127.0.0.1:8080/myDruid/stat
     */
    @GetMapping("myDruid/stat")
    public List<Map<String, Object>> druidStat() {
        List<Map<String, Object>> statDataList = DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
        return statDataList;
    }
}

src/main/java/com/wmx/reddoor/jpa/controller/DruidController.java · 汪少棠/red-door – Gitee.com

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/132766.html原文链接:https://javaforall.cn

0 人点赞