阿里出品,淘宝和支付宝专用数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。
优势
相较于c3p0、dbcp连接池
- 可以监控数据库访问性能,内置StatFilter插件可以详细统计数据库访问情况和SQL执行性能
- 可以加密数据库密码,DruidDruiver和DruidDataSource都支持PasswordCallback
- 可扩展性更好,通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件
- 通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析语义实现的。
- 性能更加优秀,简单SQL语句用时10微秒以内,复杂SQL用时30微秒
使用
使用方式有3种:
- 直接设置数据源参数并建立连接池
- XML配置数据源,读取数据源并建立连接池
- XML配置连接池,获取连接池
POM引入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.2</version>
</dependency>
方法一:直接设置数据源参数并建立连接池
@Test
public void druidPoolTest() throws SQLException {
/**
* 直接连接DRUID连接池
* 1. 配置数据源参数
* 2. 连接数据库
* 3. 预编译SQL
* 4. 执行SQL
*/
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(URL);
druidDataSource.setUsername(USERNAME);
druidDataSource.setPassword(PASSWORD);
druidDataSource.setDriverClassName(DRIVER_CLASS_NAME);
druidDataSource.setInitialSize(INITIAL_SIZE);
druidDataSource.setMaxActive(MAX_ACTIVE);
druidDataSource.setMaxWait(MAX_WAIT);
druidDataSource.setMinIdle(MIN_IDLE);
Connection connection = druidDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(QUERYSQL);
while (resultSet.next()) {
System.out.println(resultSet.getInt(1));
}
}
方法二:XML配置数据源,读取数据源并建立连接池
连接参数:druid.properties
#驱动名
driverClassName=com.mysql.jdbc.Driver
#url
url=jdbc:mysql://*.*.*.*:*/*
#用户名
user=*
#密码
password=*
#初试连接数
initialSize=5
#最大活跃数
maxTotal=5
#最大idle数
maxIdle=2
#最小idle数
minIdle=1
数据源配置:druid.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="druid.properties"/>
<bean class="com.alibaba.druid.pool.DruidDataSource" id="druidDataSource">
<property name="driverClassName" value="${driverClassName}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="url" value="${url}"/>
<property name="initialSize" value="${initialSize}"/>
<property name="maxActive" value="${maxTotal}"/>
<property name="minIdle" value="${minIdle}"/>
</bean>
</beans>
代码实现
@Test
public void druidDataSourceFromXmlTest() throws IOException, SQLException {
/**
* 从XML配置中获取数据源
* 1. 配置数据源
* 2. 获取数据库连接
* 3. 预编译SQL
* 4. 执行SQL
*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("druid.xml");
DruidDataSource druidDataSource = applicationContext.getBean("druidDataSource", DruidDataSource.class);
Connection connection = druidDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(QUERYSQL);
while (resultSet.next()) {
System.out.println(resultSet.getInt(1));
}
}
方法三:XML配置连接池,获取连接池
连接参数:druid.properties
#驱动名
driverClassName=com.mysql.jdbc.Driver
#url
url=jdbc:mysql://*.*.*.*:*/OWL
#用户名
user=*
#密码
password=*
#初试连接数
initialSize=5
#最大活跃数
maxTotal=5
#最大idle数
maxIdle=2
#最小idle数
minIdle=1
数据源配置:druid.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="druid.properties"/>
<bean class="com.alibaba.druid.pool.DruidDataSource" id="druidDataSource">
<property name="driverClassName" value="${driverClassName}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="url" value="${url}"/>
<property name="initialSize" value="${initialSize}"/>
<property name="maxActive" value="${maxTotal}"/>
<property name="minIdle" value="${minIdle}"/>
</bean>
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<property name="dataSource" ref="druidDataSource"/>
</bean>
</beans>
代码实现
@Test
public void druidPoolFromXmlTest() throws IOException, SQLException {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("druid.xml");
JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
Integer integer = jdbcTemplate.queryForObject(QUERYSQL, Integer.class);
System.out.println(integer);
}
完整参数说明
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_user}" />
<property name="password" value="${jdbc_password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
连接池监控
<!-- Druid连接池监控 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring.datasource.type= com.alibaba.druid.pool.DruidDataSource
# 初始连接数
spring.datasource.druid.initialSize= 5
# 最小连接池数量
spring.datasource.druid.minIdle= 5
# 最大连接池数量
spring.datasource.druid.maxActive= 20
# 配置间隔多久才进行一次检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.timeBetweenEvictionRunsMillis= 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.minEvictableIdleTimeMillis= 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
spring.datasource.druid.maxEvictableIdleTimeMillis= 900000
# 配置检测连接是否有效
spring.datasource.druid.validationQuery= select 'x'
# 申请连接时执行validationQuery检测连接是否有效
spring.datasource.druid.testWhileIdle= true
spring.datasource.druid.testOnBorrow= false
spring.datasource.druid.testOnReturn= false
# wall防御sql注入过滤
spring.datasource.druid.filter.wall.enabled=true
# 是否允许一次执行多条语句,缺省关闭
spring.datasource.druid.filter.wall.config.multi-statement-allow=true
# stat监控统计过滤
spring.datasource.druid.filter.stat.enabled=true
# 慢SQL记录
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=5000
spring.datasource.druid.filter.stat.merge-sql=true
# 开启druid监控统计页(数据源配置、sql监控、防御拦截、url用时统计等等) localhost:port/druid
spring.datasource.druid.StatViewServlet.loginUsername=druid
spring.datasource.druid.StatViewServlet.loginPassword=druid
spring.datasource.druid.StatViewServlet.allow=127.0.0.1
# 不拦截统计的URL
spring.datasource.druid.WebStatFilter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*