Druid是什么?
Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
怎么配置maven
Springboot:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
德鲁伊有哪些功能?
- 有监控统计功能:记录慢SQL(虽然公司DBA会帮我们记录慢SQL)。
- 防止连接泄漏。
- 数据库密码加密等。
- 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。
如果开启慢SQL记录
首先说明一下,我的SpringBoot使用2.0.6版本,它默认使用HikariCP数据库连接池,因此我们要排除掉。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
配置文件
spring.datasource.druid.filter.stat.slow-sql-millis=200
spring.datasource.druid.filter.stat.log-slow-sql=true
可以看到默认(没有这条配置 enable)会使用StatFilter。
将配置信息注入进com.alibaba.druid.filter.stat.StatFilter这个类,后面我会介绍Durid的Filter机制。
@SpringBootApplication
@Slf4j
@EnableTransactionManagement
public class DemoApplication implements CommandLineRunner {
@Autowired
private DataSource dataSource;
@Autowired
private TestService testService;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info(dataSource.toString());
new Thread(() -> testService.selectForUpdate()).start();
new Thread(() -> testService.selectForUpdate()).start();
}
}
@Transactional
public void selectForUpdate() {
jdbcTemplate.queryForObject("select id from foo where id = 1 for update", Long.class);
try {
Thread.sleep(200);
log.error(String.valueOf(System.currentTimeMillis()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我这边跑2个线程,每个线程执行一个SQL语句,对表加锁的,并维持200ms后另一个线程才能继续执行同样的SQL。这样导致SQL会出现大于200ms的情况。
这样,如果SQL语句执行时间超过200ms,则会打印出日志,我打印到了日志文件中。
责任链模式
在Servlet中Filter就是这种模式,我们应该不陌生。
我们从getConnection开始看
可以看到filter这个过滤器,它先判断是否有filter,如果有执行拦截器链filterChain,如果没有则直接获取Connection。
接下来,看看拦截器链怎么执行的。
pos执行标识目前执行到第几个Filter了,Filter是使用List类型来保存的。如果每个Filter都执行完了才会执行真正的获取连接方法。这模式是不是很简单~
说明相关配置
#是否在获得连接后检测其可用性,为true将降低性能
spring.datasource.druid.test-on-borrow=true
#是否在连接放回连接池后检测其可用性,true将降低性能
spring.datasource.druid.test-on-return=true
#是否在连接空闲一段时间后检测其可用性
spring.datasource.druid.test-while-idle=true
代码实现在DruidDataSource里。
public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {}
如果testOnBorrow为true,那么每次获得连接时先测试其可用性。