前言:
小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。 这个SpringBoot基础学习系列用来记录我学习SpringBoot框架基础知识的全过程 (这个系列是参照B站狂神的SpringBoot最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!) 之后我将会以一天一更的速度更新这个系列,还没有学习SpringBoot的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。 最后,希望能够和大家一同进步吧!加油吧!少年们!
废话不多说,让我们开始今天的学习内容吧,由于今天我们来到了SpringBoot基础学习的第七站:整合Druid数据源!
6.2 整合Druid数据源
6.2.1 Druid数据源介绍
1.Druid数据源简介
- Druid是阿里巴巴开发的一个开源的数据库连接池,结合了C3P0、DBCP和PROXOOL等DB池的优点,同时加入了日志监控
- Druid可以很好的监控DB池连接和SQL的执行情况,天生是针对监控而生的DB连接池
- Spring Boot 2.0 以上默认使用Hikari数据源,可以说Hikari与Druid都是当前Java Web上较为优秀的数据源,
2.Druid数据源常用配置参数
我们来重点介绍Spring Boot 如何集成Druid数据源,如何实现数据库监控,以下是Druid数据源的常用配置参数表:
配置 | 缺省值 | 说明 |
---|
name (数据源名称) | | 配置这个属性的意义在于,如果存在多个数据源,监控时可以通过名字来区分开;如果没有配置,将会生成一个名字,格式为:“DataSource-” + System.identifyHashCode(this) | url (url连接) | | 连接数据库的url,不同数据库不一样;例如,mysql:jdbc:mysql://localhost:3306/druid2;orcale:jdbc:orcale:thin:@localhost:1521:ocnauto | username (用户名) | | 连接数据库的用户名 | password (密码) | | 连接数据库的密码 | driverClassName (驱动名) | 根据url自动识别 | 这一项可配可不配,如果不配置Druid会根据url识别数据库类型,然后选择相应的DriverClassName | initialSize (初始化物理连接个数) | 0 | 初始化时建立物理连接的个数,初始化发生在显式调用init方法,或者第一次getConnection时 | maxActive (最大连接池数) | 8 | 最大连接池数量 | maxIdle (最大空闲数) | 8 | 已经不再使用了,配置了也没效果 | mindle | | 最小连接池数量 | maxWait (最大等待时间) | | 获取连接时最大等待时间,单位毫秒;配置了maxWait之后,缺省启用公平锁,并发效率会有所下降;如果需要可以通过配置useUnicodeLock属性为true,使用非公平锁 | poolPreparedStatements (预编译池) | false | 是否缓存preparedStatement,也就是PSCache;PSCache对支持游标的数据库性能提升巨大,比如说Oracle;在MySQL 5.5以下的版本中没有PSCache功能,建议关闭掉;MySQL 5.5以上版本有PSCache,建议开启 | maxOpenPreparedStatements (开放的最大预编译语句数) | -1 | 要启动PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true;在Druid中,不会存在Orcale下PSCache占内存过多的问题,可以把这个数值配置再大一些,比如说100 | validationQueryfont> (查询是否生效) | | 用来检测连接是否有效的SQL,要求是一个查询语句;如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用;在MySQL中通知Select ‘X’,在Oracle中通常为Select 1 from dual | testOnBorrow (检测引入查询语句的连接是否有效) | false | 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 | testOnReturn (测试归还连接是否有效) | false | 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 | testWhiteIdle (检测空闲连接时间是否大于回收和运行间隔) | false | 建议配置为true,不影响性能,并且保证安全性;申请连接时检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validatioQuery检测连接是否有效 | timeBetweenEvictionRunsMillis (回收和运行时间间隔) | | 有两个含义:Destroy线程检测连接的间隔时间; testWhiteIdle的判断依据 | numTestsPerEvictionRun (每个回收和运行的测试数量) | | 不再使用,一个DruidDatsSource只支持一个EvictionRun | minEvictableTimeMillis (最小回收时间) | | Destroy线程,如果检测到当前连接的最后活跃时间和当前时间大于minEvictableTimeMillis,则关闭当前连接 | connectionInitSqls (连接初始化SQL) | | 物理连接初始化时执行的SQL | exceptionSorter (异常分类机) | 根据dbType (数据库类型)自动识别 | 当数据库抛出一些不可恢复的异常时,抛弃连接 | filters(过滤器) | | 属性类型是字符串,通过别名的方式配置扩展插件;常用的插件有:监控统计的filter:stat;日志用的filter:log4j;防御SQL注入的filter:wall | proxyFilters (动态过滤器) | | 类型是List<com.alibaba.druid.filter.Filter>,如果同时配置filters和ProxyFilters,是组合关系,并非替换关系 |
6.2.2 引入Druid数据源
1.导入资源依赖和修改配置文件
1-1 导Druid的资源依赖
- 在pom.xml配置文件中导入Druid和log4j的资源依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 在外部资源中查看druid的相关资源依赖
1-2 修改核心配置文件
server:
port: 8888
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 300000
minEvictableIdleTimeMillis: 300000
validationQuery: Select 1 from dual
testWhiteIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,log4j,wall
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
2.查看修改后的数据源
2-1 启动测试类
package com.kuang;
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.SQLException;
@SpringBootTest
class Springboot04DataApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
System.out.println(dataSource.getClass());
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
2-2 测试结果
6.2.3 自定义数据源
1.查看动态注册器Bean源码
- 在IDEA中搜索DynamicRegistrationBean类,查看其如何实现动态注册
public abstract class DynamicRegistrationBean<D extends Dynamic> extends RegistrationBean {
private static final Log logger = LogFactory.getLog(RegistrationBean.class);
private String name;
private boolean asyncSupported = true;
private Map<String, String> initParameters = new LinkedHashMap();
public DynamicRegistrationBean() {
}
public void setName(String name) {
Assert.hasLength(name, "Name must not be empty");
this.name = name;
}
public void setAsyncSupported(boolean asyncSupported) {
this.asyncSupported = asyncSupported;
}
public boolean isAsyncSupported() {
return this.asyncSupported;
}
public void setInitParameters(Map<String, String> initParameters) {
Assert.notNull(initParameters, "InitParameters must not be null");
this.initParameters = new LinkedHashMap(initParameters);
}
}
2.编写自定义DruidConfig
package com.kuang.config;
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;
import java.util.Map;
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource() {
return new DruidDataSource();
}
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
HashMap<String, String>initParameters = new HashMap<>();
initParameters.put("loginUsername","admin");
initParameters.put("loginPassword","123456");
initParameters.put("allow","");
bean.setInitParameters(initParameters);
return bean;
}
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String, String> initParameters = new HashMap<>();
initParameters.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParameters);
return bean;
}
}
6.2.4 Druid登录验证和后台SQL监控
1.Druid登录验证测试
- 启动SpringBoot项目后,在地址链接后面加上/druid/login.html,然后就可以进入到登录界面了
- 输入在DruidConfig配置类中设置好的管理员用户名和密码,通过验证后进入到监控后台
- 成功进入到Druid监控后台首页,可以看到一些相关信息,例如数据库和数据源驱动,以及Java的JDK版本等
2.后台SQL监控测试
2-1 访问用户列表和查看SQL监控
package com.kuang.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
public class JdbcController {
@Autowired
JdbcTemplate jdbcTemplate;
@RequestMapping("/getList")
public List<Map<String, Object>> getUserList() {
String sql = "select * from user";
List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
return list_maps;
}
}
结果:查询用户列表信息成功!
结果:SQL监控记录了执行查询SQL语句的操作!
2-2 删除用户信息
package com.kuang.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
public class JdbcController {
@Autowired
JdbcTemplate jdbcTemplate;
@RequestMapping("/deleteUser/{userId}")
public String delteUser(@PathVariable("userId") int id) {
String sql = "delete from mybatis.user where id=?";
jdbcTemplate.update(sql,id);
return "Delete-OK";
}
}
结果:删除指定用户信息成功!
2-3 查看Druid的后台SQL监控
结果:SQL监控记录了执行删除SQL语句操作!
结论:
通过上面的测试,我们体会到了Druid数据源强大的SQL监控功能,不仅能够监测SQL语句的执行,包括执行次数、执行时间和更新行数、读取行数,以及最大并发操作和执行时间分布
3.Druid的SQL防火墙
- 当然,Druid除了强大的SQL监控功能,同时还具有SQL防火墙这一功能,能够统计各种SQL执行次数和函数的调用,以及统计SQL防御的白名单和黑名单,可见其功能十分强大!
好了,今天的有关 SpringBoot基础学习之整合Druid数据源 的学习就到此结束啦,欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连,我们下期见,拜拜啦!
参考视频链接:https://www.bilibili.com/video/BV1PE411i7CV(【狂神说Java】SpringBoot最新教程IDEA版通俗易懂)
|