springboot整合druid数据库连接池

Druid是阿里巴巴的一个数据库连接池开源框架,准确来说它不仅仅包括数据库连接池这么简单,Druid在监控、可扩展性、稳定性和性能方面都有明显的优势。Druid提供了Filter-Chain模式的扩展API,可以自己编写Filter拦截JDBC中的任何方法,可以在上面做任何事情,比如说性能监控、SQL审计、用户名密码加密、日志等等。

一、主流连接池对比
常用的主流开源数据库连接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等

C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统,代码600KB左右。

DBCP (Database Connection Pool):由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。

Tomcat Jdbc Pool:Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。Tomcat从7.0开始引入了新增连接池模块叫做Tomcat jdbc pool,基于Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通过异步方式获取连接,支持高并发应用环境,超级简单核心文件只有8个,支持JMX,支持XA Connection。连接远程的数据库,而网络质量很差,经常断开连接。用dbcp,经常死锁,Druid在这种恶劣的工况下,也不行。最后用的tomcat7连接池,搞定。

BoneCP:官方说法BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,根据某些测试数据显示,BoneCP的速度是最快的,要比当时第二快速的连接池快25倍左右,完美集成到一些持久化产品如Hibernate和DataNucleus中。BoneCP特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织,100%单元测试分支代码覆盖率;代码40KB左右。

Druid:Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上。

二、springboot整合druid
springboot整合有两种方式,第一种方式使用java配置,第二种方式使用注解配置,下面我们分别使用两种方式进行介绍。

准备工作:引入依赖包

	
	
		mysql
		mysql-connector-java
		5.1.35
	
	
	
		com.alibaba
		druid-spring-boot-starter
		1.1.0
	
	
	
		org.projectlombok
		lombok
		1.16.20
	
	
	
		log4j
		log4j
		1.2.16
		compile
	

为了方便创建实体类,引入lombokjar包,省缺set和get方法,不引用log4jjar包会报错。

配置文件application.properties

	# 数据库配置
	spring.datasource.name=test
	spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
	spring.datasource.username=root
	spring.datasource.password=
	spring.datasource.driver-class-name=com.mysql.jdbc.Driver
	spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
	
	######################### Druid连接池的配置信息  #################
	#初始化连接大小
	spring.druid.initialSize=5
	#最小连接池数量
	spring.druid.minIdle=5
	#最大连接池数量
	spring.druid.maxActive=20
	#获取连接时最大等待时间,单位毫秒
	spring.druid.maxWait=60000
	#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
	spring.druid.timeBetweenEvictionRunsMillis=60000
	#配置一个连接在池中最小生存的时间,单位是毫秒
	spring.druid.minEvictableIdleTimeMillis=300000
	#测试连接
	spring.druid.validationQuery=SELECT 1 FROM DUAL
	#申请连接的时候检测,建议配置为true,不影响性能,并且保证安全性
	spring.druid.testWhileIdle=true
	#获取连接时执行检测,建议关闭,影响性能
	spring.druid.testOnBorrow=false
	#归还连接时执行检测,建议关闭,影响性能
	spring.druid.testOnReturn=false
	#是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭
	spring.druid.poolPreparedStatements=false
	#开启poolPreparedStatements后生效
	spring.druid.maxPoolPreparedStatementPerConnectionSize=20
	#配置扩展插件,常用的插件有=>stat:监控统计  log4j:日志  wall:防御sql注入
	spring.druid.filters=stat,wall,log4j
	#通过connectProperties属性来打开mergeSql功能;慢SQL记录
	spring.druid.connectionProperties='druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000'
	
	######################### Druid监控的配置信息  #################
	druid.monitor.servletUrl=/druid/*
	druid.monitor.allow=127.0.0.1
	druid.monitor.deny=
	druid.monitor.loginUsername=admin
	druid.monitor.loginPassword=admin
	druid.monitor.resetEnable=false
	druid.monitor.logSlowSql=true
	druid.monitor.filterUrl=/*
	druid.monitor.exclustions='*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
	druid.monitor.profileEnable=true
	druid.monitor.principalCookieName=USER_COOKIE
	druid.monitor.principalSessionName=USER_SESSION

方式一:使用java配置

1、读取数据库配置

	package com.soft.springboot.config;
	
	import lombok.Data;
	import org.springframework.boot.context.properties.ConfigurationProperties;
	import org.springframework.stereotype.Component;
	
	/**
	 * 数据库属性
	 * Created by USER on 2019/5/31.
	 */
	@Component
	@ConfigurationProperties(prefix = "spring.datasource")
	@Data
	public class DataSourceProperties {
	    private String name;
	    private String url;
	    private String username;
	    private String password;
	    private String driverClassName;
	}

2、读取druid连接池配置

	package com.soft.springboot.config;
	
	import lombok.Data;
	import org.springframework.boot.context.properties.ConfigurationProperties;
	import org.springframework.stereotype.Component;
	
	/**
	 *  druid数据源属性
	 * Created by USER on 2019/5/31.
	 */
	@Component
	@ConfigurationProperties(prefix = "spring.druid")
	@Data
	public class DruidDataSourceProperties {
	    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;
	}

3、读取druid监控配置

	package com.soft.springboot.config;
	
	import lombok.Data;
	import org.springframework.boot.context.properties.ConfigurationProperties;
	import org.springframework.stereotype.Component;
	
	/**
	 *  druid监控服务属性
	 * Created by USER on 2019/5/31.
	 */
	@Component
	@ConfigurationProperties(prefix = "druid.monitor")
	@Data
	public class DruidMonitorProperties {
	    // 监测服务配置
	    private String servletUrl;
	    private String allow;
	    private String deny;
	    private String loginUsername;
	    private String loginPassword;
	    private String resetEnable;
	    private String logSlowSql;
	    // 监测过滤配置
	    private String filterUrl;
	    private String exclustions;
	    private String profileEnable;
	    private String principalCookieName;
	    private String principalSessionName;
	}

4、配置druid连接池

	package com.soft.springboot.config;
	
	import com.alibaba.druid.pool.DruidDataSource;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import org.springframework.context.annotation.Primary;
	
	import javax.sql.DataSource;
	import java.sql.SQLException;
	
	/**
	 * druid连接池配置
	 * Created by USER on 2019/5/31.
	 */
	@Configuration
	public class DruidDataSourceConfigurater {
	
	    @Autowired
	    private DataSourceProperties dataSourceProperties;
	
	    @Autowired
	    private DruidDataSourceProperties druidDataSourceProperties;
	
	    @Bean(name="dataSource",destroyMethod = "close", initMethod="init")
	    @Primary
	    public DataSource dataSource() {
	        DruidDataSource dataSource = new DruidDataSource();
	        dataSource.setName(dataSourceProperties.getName());
	        dataSource.setUrl(dataSourceProperties.getUrl());
	        dataSource.setUsername(dataSourceProperties.getUsername());
	        dataSource.setPassword(dataSourceProperties.getPassword());
	        dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
	
	        dataSource.setInitialSize(druidDataSourceProperties.getInitialSize());
	        dataSource.setMinIdle(druidDataSourceProperties.getMinIdle());
	        dataSource.setMaxActive(druidDataSourceProperties.getMaxActive());
	        dataSource.setMaxWait(druidDataSourceProperties.getMaxWait());
	        dataSource.setTimeBetweenEvictionRunsMillis(druidDataSourceProperties.getTimeBetweenEvictionRunsMillis());
	        dataSource.setMinEvictableIdleTimeMillis(druidDataSourceProperties.getMinEvictableIdleTimeMillis());
	        dataSource.setValidationQuery(druidDataSourceProperties.getValidationQuery());
	        dataSource.setTestWhileIdle(druidDataSourceProperties.isTestWhileIdle());
	        dataSource.setTestOnBorrow(druidDataSourceProperties.isTestOnBorrow());
	        dataSource.setTestOnReturn(druidDataSourceProperties.isTestOnReturn());
	        dataSource.setPoolPreparedStatements(druidDataSourceProperties.isPoolPreparedStatements());
	        dataSource.setMaxPoolPreparedStatementPerConnectionSize(druidDataSourceProperties.getMaxPoolPreparedStatementPerConnectionSize());
	        try {
	            dataSource.setFilters(druidDataSourceProperties.getFilters());
	        } catch (SQLException e) {
	            e.printStackTrace();
	        }
	        dataSource.setConnectionProperties(druidDataSourceProperties.getConnectionProperties());
	
	        return dataSource;
	    }
	}

5、配置druid监控服务

	package com.soft.springboot.config;
	
	import com.alibaba.druid.support.http.StatViewServlet;
	import com.alibaba.druid.support.http.WebStatFilter;
	import org.springframework.beans.factory.annotation.Autowired;
	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;
	
	/**
	 * Druid监控配置
	 * Created by USER on 2019/5/31.
	 */
	@Configuration
	public class DruidMonitorConfigurater {
	
	    @Autowired
	    private DruidMonitorProperties monitorProperties;
	
	    @Bean
	    public ServletRegistrationBean statViewServlet() {
	        ServletRegistrationBean registrationBean = new ServletRegistrationBean();
	        // 设置Servlet
	        registrationBean.setServlet(new StatViewServlet());
	        // 设置监控服务url
	        registrationBean.addUrlMappings(monitorProperties.getServletUrl());
	        // 设置访问白名单
	        registrationBean.addInitParameter("allow", monitorProperties.getAllow());
	        // 设置访问黑名单
	        registrationBean.addInitParameter("deny", monitorProperties.getDeny());
	        // 设置登录账号
	        registrationBean.addInitParameter("loginUsername", monitorProperties.getLoginUsername());
	        // 设置登录密码
	        registrationBean.addInitParameter("loginPassword", monitorProperties.getLoginPassword());
	        // 设置是否可以重置数据
	        registrationBean.addInitParameter("resetEnable", monitorProperties.getResetEnable());
	        // 配置打印慢的sql
	        registrationBean.addInitParameter("logSlowSql", monitorProperties.getLogSlowSql());
	        return registrationBean;
	    }
	
	    @Bean
	    public FilterRegistrationBean webStatFilter() {
	        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
	        // 设置过滤器
	        registrationBean.setFilter(new WebStatFilter());
	        // 添加过滤规则
	        registrationBean.addUrlPatterns(monitorProperties.getFilterUrl());
	        // 设置忽略内容
	        registrationBean.addInitParameter("exclustions", monitorProperties.getExclustions());
	        // 监控单个url调用的sql列表
	        registrationBean.addInitParameter("profileEnable", monitorProperties.getProfileEnable());
	        registrationBean.addInitParameter("principalCookieName", monitorProperties.getPrincipalCookieName());
	        registrationBean.addInitParameter("principalSessionName", monitorProperties.getPrincipalSessionName());
	
	        return registrationBean;
	    }
	}

方法二:使用注解配置

1、配置druid拦截器

package com.soft.springboot.config;

import com.alibaba.druid.support.http.WebStatFilter;

import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
/**
 * Druid的拦截器配置
 * Created by USER on 2019/5/31.
 */
@WebFilter(filterName = "DruidFilter", urlPatterns = "/*", initParams = {
        @WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源
})
public class DruidFilter extends WebStatFilter {
}

2、配置druid监控服务

package com.soft.springboot.config;

import com.alibaba.druid.support.http.StatViewServlet;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

/**
 * Druid监控服务配置
 * Created by USER on 2019/5/31.
 */
@WebServlet(urlPatterns = "/druid/*",
        initParams = {
                @WebInitParam(name = "allow", value = "127.0.0.1"),// IP白名单 (没有配置或者为空,则允许所有访问)
                @WebInitParam(name = "deny", value = "192.168.16.111"),// IP黑名单 (存在共同时,deny优先于allow)
                @WebInitParam(name = "loginUsername", value = "admin"),// 用户名
                @WebInitParam(name = "loginPassword", value = "admin"),// 密码
                @WebInitParam(name = "resetEnable", value = "false")// 禁用HTML页面上的“Reset All”功能
        })
public class DruidServlet extends StatViewServlet {

    private static final long serialVersionUID = -6085007333934055609L;
}

3、对于基于注解的Filter和Servlet需要在SpringBoot的启动类上打上自动扫描注解

package com.soft.springboot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@ServletComponentScan
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

启动springboot,访问http://localhost:8080/druid/

你可能感兴趣的:(springboot)