目录
Druid 简介
Druid是阿里巴巴开源的数据库连接池,号称是Java语言中最好的数据库连接池,能够提供强大的监控和扩展功能。GitHub地址:https://github.com/alibaba/druid。
Druid有以下优点:
1) 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
2) 替换DBCP和C3P0,Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
3) 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDriver和DruidDataSource都支持PasswordCallback。
4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
5) 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC层的扩展插件。
本文将对如何在Springboot中使用Druid数据库连接池进行简单示例和介绍,为简单起见,本文使用了Spring Jpa来进行数据库操作,项目的完整目录层次如下图所示。
添加依赖与配置
为了使用Druid和Spring Data JPA,需要在工程POM文件中引入它们的Maven依赖。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加MySQL依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 添加JPA依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 添加druid依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
在application.yml 核心配置文件中除了要定义MYSQL数据库连接信息外,还需要添加如下JPA相关配置。
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
platform: mysql
type: com.alibaba.druid.pool.DruidDataSource
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initialSize: 1
minIdle: 3
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
#useGlobalDataSourceStat: true
jpa:
# 配置 DBMS 类型
database: MYSQL
# 配置是否将执行的 SQL 输出到日志
show-sql: true
properties:
hibernate:
hbm2ddl:
# 配置开启自动更新表结构
auto: update
配置数据源
在Spring中使用Druid数据源非常简单方便,只需要创建一个DruidDataSource类型的数据源并将其纳入到Spring容器中进行管理即可。
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidDataSourceConfig {
private String url;
private String username;
private String password;
private String driverClassName;
private int initialSize;
private int minIdle;
private int maxActive;
private int maxWait;
private int timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String filters;
private String connectionProperties;
// 解决 spring.datasource.filters=stat,wall,log4j 无法正常注册
@Bean
@Primary // 在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
// configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
System.err.println("druid configuration initialization filter: " + e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
// 此处省略属性的get和set方法
}
配置Druid监控统计功能
基于Druid的Filter-Chain扩展机制,Druid提供了3个非常有用的具有监控统计功能的Filter:
- StatFilter 用于统计监控信息;
- WallFilter 基于SQL语义分析来实现防御SQL注入攻击;
- LogFilter 用于输出JDBC执行的日志。
如果在项目中需要使用Druid提供的这些监控统计功能,可以通过以下两种途径进行配置。
方式一(基于Servlet 3.0 注解的配置)
对于使用Servlet 3.0的项目,在启动类上加上注解 @ServletComponentScan 启用Servlet自动扫描,并在自定义的Servlet或Filter上加上注解@WebServlet或@WebFilter使其能够被自动发现。
@SpringBootApplication
@ServletComponentScan
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
/**
* druid数据源状态监控.
*/
@WebServlet(urlPatterns = "/druid/*", initParams = {
// IP白名单 (没有配置或者为空,则允许所有访问)
@WebInitParam(name = "allow", value = "192.168.1.101,127.0.0.1"),
// IP黑名单 (存在共同时,deny优先于allow)
@WebInitParam(name = "deny", value = "192.168.1.100"),
// 用户名
@WebInitParam(name = "loginUsername", value = "admin"),
// 密码
@WebInitParam(name = "loginPassword", value = "admin"),
// 禁用HTML页面上的“Reset All”功能
@WebInitParam(name = "resetEnable", value = "false") })
@SuppressWarnings("serial")
public class DruidStatViewServlet extends StatViewServlet {
}
/**
* druid过滤器.
*/
@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*", initParams = {
// 忽略资源
@WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*") })
public class DruidStatFilter extends WebStatFilter {
}
方式二(基于Spring注解的配置)
使用Spring的注解@Bean对自定义的Servlet或Filter进行注册,Servlet使用ServletRegistrationBean进行注册,Filter使用FilterRegistrationBean进行注册。
@SpringBootConfiguration
public class DruidMonitorConfig {
private static final Logger logger = LoggerFactory.getLogger(DruidMonitorConfig.class);
@Bean
public ServletRegistrationBean servletRegistrationBean() {
logger.info("init Druid Monitor Servlet ...");
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),
"/druid/*");
// IP白名单
servletRegistrationBean.addInitParameter("allow", "192.168.1.101,127.0.0.1");
// IP黑名单(共同存在时,deny优先于allow)
servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
// 控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "admin");
// 是否能够重置数据 禁用HTML页面上的“Reset All”功能
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
配置JPA
创建一个用户POJO实体类,用来进行示例。
@Entity
@Table(name = "tbl_user") // 指定关联的数据库的表名
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 主键ID
private String name; // 姓名
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}
再创建一个用户的数据库访问资源库接口。
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
}
在UserController控制器中添加两个方法,一个用来添加用户,一个用来查看所有用户。
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserRepository userRepository;
@RequestMapping("/add")
public Object add(@RequestParam(name = "name", required = true) String name) {
User user = new User();
user.setName(name);
userRepository.save(user);
return user;
}
@RequestMapping("/list")
public Object list() {
Iterable<User> users = userRepository.findAll();
return users;
}
}
应用测试
启动应用,先访问地址:http://localhost:8080/user/add?name=Tracy,为用户添加一个姓名为Tracy的用户。
再访问地址:http://localhost:8080/user/list,查看所有用户。
最后访问地址:http://localhost:8080/druid/,登录之后,即可查看Druid数据源的配置及SQL统计情况。
本文项目源码已上传至CSDN,资源地址:https://download.csdn.net/download/pengjunlee/10374589
百度网盘:
链接:https://pan.baidu.com/s/1x6Fmqb9IXLNR3cuQDawf1A
提取码:jeo5