什么是druid?
Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计SQL信息、SQL性能收集、SQL注入检查、SQL翻译等,程序员可以通过定制来实现自己需要的功能。
Druid支持哪些数据库?
Druid支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。
Druid针对Oracle和MySql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。
为什么说Druid是“最好的数据库连接池”?体现在哪些方面?这是如何实现的?
阿里巴巴是一个重度使用关系数据库的公司,我们在生产环境中大量的使用Druid,通过长期在极高负载的生产环境中实际使用、修改和完善,让Druid逐步发展成最好的数据库连接池。Druid在监控、可扩展性、稳定性和性能方面都有明显的优势。
首先,强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况。
其次,方便扩展。Druid提供了Filter-Chain模式的扩展API,可以自己编写Filter拦截JDBC中的任何方法,可以在上面做任何事情,比如说性能监控、SQL审计、用户名密码加密、日志等等。
Druid内置提供了用于监控的StatFilter、日志输出的Log系列Filter、防御SQL注入攻击的WallFilter。
阿里巴巴内部实现了用于数据库密码加密的CirceFilter,以及和Web、Spring关联监控的DragoonStatFilter。
第三,Druid集合了开源和商业数据库连接池的优秀特性,并结合阿里巴巴大规模苛刻生产环境的使用经验进行优化。
注:第一部分为代码,第二部分为演示Druid数据源操作的截图,完整代码可在github下载。
github地址:https://github.com/zjh746140129/Spring-Boot2.0
项目结构截图:
1、编写用户类
package com.boot.entity;
import javax.persistence.*;
/**
* Created by zhoujh on 2018/7/20.
*/
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue
private Integer id;
@Column(length = 50)
private String name;
@Column(length = 50)
private String word;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
}
2、编写接口
package com.boot.repository;
import com.boot.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Created by zhoujh on 2018/7/20.
*/
public interface UserDao extends JpaRepository {
}
3、编写controller
package com.boot.controller;
import com.boot.entity.User;
import com.boot.repository.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Created by zhoujh on 2018/7/20.
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserDao userDao;
@GetMapping(value = "/all")
public List findAllUser() {
return userDao.findAll();
}
@GetMapping("/find/{id}")
public User findOneUser(Integer id) {
return userDao.getOne(id);
}
@DeleteMapping("/delete/{id}")
public void deleteUser(Integer id) {
userDao.deleteById(id);
}
@PostMapping("/add")
public void addStudentRestful(User user) {
userDao.save(user);
}
@PutMapping("/update")
public void updateUser(User user) {
userDao.save(user);
}
}
4、编写durid的config、filter
package com.boot.config;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
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 com.alibaba.druid.pool.DruidDataSource; //这个包容易导入错误
import com.alibaba.druid.support.http.StatViewServlet; //这个包容易导入错误
import com.alibaba.druid.support.http.WebStatFilter; //这个包容易导入错误
/**
* Created by zhoujh on 2018/7/20.
*/
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid() {
return new DruidDataSource();
}
// 配置Druid的监控
// 1、配置一个管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map initParams = new HashMap<>();
// 监控页面登录用户名
initParams.put("loginUsername", "admin");
// 监控页面登录用户密码
initParams.put("loginPassword", "123456");
// ip白名单(没有配置或者为空,则允许所有访问)
initParams.put("allow", "");
// ip黑名单(如果某个ip同时存在,deny优先于allow)
initParams.put("deny", "");
bean.setInitParameters(initParams);
return bean;
}
// 2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map initParams = new HashMap<>();
// 不拦截的静态资源
initParams.put("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*");
bean.setInitParameters(initParams);
// 拦截所有的请求
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
package com.boot.config;
import com.alibaba.druid.support.http.WebStatFilter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
/**
* Created by zhoujh on 2018/7/20.
*/
@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*", initParams = {
@WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源
})
public class DruidStatFilter extends WebStatFilter {
}
package com.boot.config;
import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
/**
* Created by zhoujh on 2018/7/20.
*/
@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/druid/*", initParams = {
// IP白名单
// (没有配置或者为空,则允许所有访问)
@WebInitParam(name = "allow", value = ""),
// IP黑名单 (存在共同时,deny优先于allow)
@WebInitParam(name = "deny", value = ""),
// 用户名
@WebInitParam(name = "loginUsername", value = "admin"),
// 密码
@WebInitParam(name = "loginPassword", value = "123456"),
// 禁用HTML页面上的“Reset All”功能
@WebInitParam(name = "resetEnable", value = "false")
})
public class DruidStatViewServlet extends StatViewServlet {
private static final long serialVersionUID = 1L;
}
5、启动类
package com.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BooDruidApplication {
public static void main(String[] args) {
SpringApplication.run(BooDruidApplication.class, args);
}
}
6、配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/school_score
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
server.port=8099
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
# 校验SQL,Oracle配置 spring.datasource.validationQuery=SELECT 1 FROM DUAL,如果不配validationQuery项,则下面三项配置无用
spring.datasource.validationQuery=SELECT 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall
#spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;
druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true
7、完整pom.xml
4.0.0
com.boot
boo-druid
0.0.1-SNAPSHOT
jar
boo-druid
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
mysql
mysql-connector-java
runtime
com.alibaba
druid-spring-boot-starter
1.1.9
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
1、查询所有,访问 http://localhost:8099/user/all
2、查看druid监控,http://localhost:8099/druid/login.html ,用户名是在config配置的admin和123456