
在 Java 开发中,数据库连接池是提升系统性能的关键组件,却也是最容易被忽视的技术点。当你的应用从 "能跑" 迈向 "能扛",连接池的选择和配置将直接决定系统的稳定性与吞吐量。本文将深入对比主流数据库连接池的优劣,重点剖析 Druid 的核心优势,并通过完整实战案例带你掌握 Druid 的高级用法,让你的数据库操作从 "蹒跚学步" 到 "健步如飞"。
数据库连接是一种昂贵的资源,建立连接需要经过 TCP 握手、权限验证等一系列操作,耗时通常在毫秒级甚至更高。在高并发场景下,频繁创建和关闭连接会导致严重的性能瓶颈。
数据库连接池的核心思想是 "池化管理":预先创建一定数量的数据库连接,用户请求时直接从池中获取连接,使用完毕后归还而非关闭。这种机制能显著减少连接建立和关闭的开销,提升系统响应速度和并发处理能力。
连接池的工作流程可以概括为以下几个步骤:

连接池的关键参数包括:
目前 Java 生态中常用的数据库连接池有:Druid、HikariCP、C3P0、DBCP2,它们各有特点:
特性 | Druid | HikariCP | C3P0 | DBCP2 |
|---|---|---|---|---|
性能 | 优秀 | 优秀 | 一般 | 良好 |
监控能力 | 强大(内置监控页面) | 基础 | 弱 | 弱 |
扩展性 | 高(支持插件机制) | 中 | 低 | 中 |
稳定性 | 高 | 高 | 中 | 中 |
功能丰富度 | 高(防 SQL 注入等) | 中 | 中 | 中 |
社区活跃度 | 高 | 高 | 低 | 中 |
配置复杂度 | 中 | 低 | 高 | 中 |
HikariCP 以极致的性能著称,代码精简,适合对性能有极高要求且不需要复杂功能的场景;C3P0 历史悠久但性能一般,逐渐被淘汰;DBCP2 作为 Apache 的产品,稳定性不错但功能相对简单;而 Druid 则在性能、功能和监控方面取得了很好的平衡,尤其适合企业级应用。
Druid 是阿里巴巴开源的数据库连接池,不仅具备出色的性能,还提供了丰富的监控和扩展功能,被誉为 "数据库连接池中的瑞士军刀"。
Druid 的架构设计采用了分层和插件化思想,核心组件包括:

接下来,我们将通过一个完整的实战案例,展示如何在 Spring Boot 项目中集成和使用 Druid,包括基本配置、监控设置、高级特性等。
我们将使用以下技术栈:
首先创建一个 Spring Boot 项目,在 pom.xml 中添加必要的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>druid-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>druid-demo</name>
<description>Demo project for Druid</description>
<properties>
<java.version>17</java.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<druid.version>1.2.20</druid.version>
<mysql.version>8.0.33</mysql.version>
<lombok.version>1.18.30</lombok.version>
<fastjson2.version>2.0.32</fastjson2.version>
<guava.version>32.1.3-jre</guava.version>
<springdoc.version>2.1.0</springdoc.version>
</properties>
<dependencies>
<!-- Spring Boot 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据库连接 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<!-- FastJSON2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<!-- Guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- Swagger3 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建一个简单的用户表用于演示:
CREATE DATABASE IF NOT EXISTS druid_demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE druid_demo;
CREATE TABLE IF NOT EXISTS `user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`age` int DEFAULT NULL COMMENT '年龄',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
在 application.yml 中配置 Druid 和数据源信息:
spring:
datasource:
druid:
# 数据库连接信息
url: jdbc:mysql://localhost:3306/druid_demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 连接池配置
initial-size: 5 # 初始连接数
max-active: 20 # 最大连接数
min-idle: 5 # 最小空闲连接数
max-wait: 60000 # 获取连接时的最大等待时间(毫秒)
# 连接有效性检测配置
validation-query: SELECT 1 # 验证连接有效性的SQL
test-on-borrow: false # 从连接池获取连接时是否检测有效性
test-on-return: false # 归还连接时是否检测有效性
test-while-idle: true # 空闲时是否检测有效性
time-between-eviction-runs-millis: 60000 # 检测间隔时间(毫秒)
min-evictable-idle-time-millis: 300000 # 连接最小空闲时间(毫秒)
# 日志配置
filters: stat,wall,log4j2 # 启用的过滤器:监控统计、防火墙、日志
filter:
stat:
enabled: true
log-slow-sql: true # 记录慢SQL
slow-sql-millis: 1000 # 慢SQL阈值(毫秒)
merge-sql: true # 合并同类SQL
wall:
enabled: true
config:
drop-table-allow: false # 禁止删除表操作
# 监控配置
stat-view-servlet:
enabled: true # 启用监控页面
url-pattern: /druid/* # 监控页面访问路径
login-username: admin # 监控页面登录用户名
login-password: admin # 监控页面登录密码
reset-enable: false # 是否允许重置监控数据
web-stat-filter:
enabled: true # 启用Web监控
url-pattern: /* # 监控所有URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # 排除的资源
# MyBatis-Plus配置
mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml
type-aliases-package: com.example.druiddemo.entity
configuration:
map-underscore-to-camel-case: true # 下划线转驼峰
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl # 日志实现
# 日志配置
logging:
level:
com.example.druiddemo: debug
com.alibaba.druid: info
# 服务器配置
server:
port: 8080
创建 User 实体类:
package com.example.druiddemo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 用户实体类
*
* @author ken
*/
@Data
@TableName("user")
public class User {
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 邮箱
*/
private String email;
/**
* 年龄
*/
private Integer age;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
创建 UserMapper 接口:
package com.example.druiddemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.druiddemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
/**
* 用户Mapper接口
*
* @author ken
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
创建 UserService 接口和实现类:
package com.example.druiddemo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.druiddemo.entity.User;
import java.util.List;
/**
* 用户服务接口
*
* @author ken
*/
public interface UserService extends IService<User> {
/**
* 创建用户
*
* @param user 用户信息
* @return 创建的用户
*/
User createUser(User user);
/**
* 根据ID获取用户
*
* @param id 用户ID
* @return 用户信息
*/
User getUserById(Long id);
/**
* 获取所有用户
*
* @return 用户列表
*/
List<User> getAllUsers();
/**
* 更新用户
*
* @param user 用户信息
* @return 是否更新成功
*/
boolean updateUser(User user);
/**
* 删除用户
*
* @param id 用户ID
* @return 是否删除成功
*/
boolean deleteUser(Long id);
}
package com.example.druiddemo.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.druiddemo.entity.User;
import com.example.druiddemo.mapper.UserMapper;
import com.example.druiddemo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.List;
/**
* 用户服务实现类
*
* @author ken
*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
/**
* 创建用户
*
* @param user 用户信息
* @return 创建的用户
*/
@Override
@Transactional(rollbackFor = Exception.class)
public User createUser(User user) {
log.info("创建用户: {}", user);
if (ObjectUtils.isEmpty(user)) {
throw new IllegalArgumentException("用户信息不能为空");
}
baseMapper.insert(user);
return user;
}
/**
* 根据ID获取用户
*
* @param id 用户ID
* @return 用户信息
*/
@Override
public User getUserById(Long id) {
log.info("根据ID获取用户: {}", id);
if (ObjectUtils.isEmpty(id)) {
throw new IllegalArgumentException("用户ID不能为空");
}
return baseMapper.selectById(id);
}
/**
* 获取所有用户
*
* @return 用户列表
*/
@Override
public List<User> getAllUsers() {
log.info("获取所有用户");
return baseMapper.selectList(new QueryWrapper<>());
}
/**
* 更新用户
*
* @param user 用户信息
* @return 是否更新成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateUser(User user) {
log.info("更新用户: {}", user);
if (ObjectUtils.isEmpty(user) || ObjectUtils.isEmpty(user.getId())) {
throw new IllegalArgumentException("用户ID不能为空");
}
return baseMapper.updateById(user) > 0;
}
/**
* 删除用户
*
* @param id 用户ID
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteUser(Long id) {
log.info("删除用户: {}", id);
if (ObjectUtils.isEmpty(id)) {
throw new IllegalArgumentException("用户ID不能为空");
}
return baseMapper.deleteById(id) > 0;
}
}创建 UserController:
package com.example.druiddemo.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.druiddemo.entity.User;
import com.example.druiddemo.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.util.ObjectUtils;
import java.util.List;
/**
* 用户控制器
*
* @author ken
*/
@Slf4j
@RestController
@RequestMapping("/api/users")
@Tag(name = "用户管理", description = "用户CRUD操作")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
/**
* 创建用户
*
* @param user 用户信息
* @return 创建的用户
*/
@PostMapping
@Operation(summary = "创建用户", description = "添加新用户到系统")
public ResponseEntity<User> createUser(
@Parameter(description = "用户信息", required = true) @RequestBody User user) {
User createdUser = userService.createUser(user);
return ResponseEntity.ok(createdUser);
}
/**
* 根据ID获取用户
*
* @param id 用户ID
* @return 用户信息
*/
@GetMapping("/{id}")
@Operation(summary = "根据ID获取用户", description = "通过用户ID查询用户详情")
public ResponseEntity<User> getUserById(
@Parameter(description = "用户ID", required = true) @PathVariable Long id) {
User user = userService.getUserById(id);
if (ObjectUtils.isEmpty(user)) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(user);
}
/**
* 获取所有用户
*
* @return 用户列表
*/
@GetMapping
@Operation(summary = "获取所有用户", description = "查询系统中所有用户")
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
/**
* 分页获取用户
*
* @param page 页码
* @param size 每页数量
* @return 分页用户列表
*/
@GetMapping("/page")
@Operation(summary = "分页获取用户", description = "分页查询系统中的用户")
public ResponseEntity<IPage<User>> getUsersByPage(
@Parameter(description = "页码", required = true) @RequestParam(defaultValue = "1") Integer page,
@Parameter(description = "每页数量", required = true) @RequestParam(defaultValue = "10") Integer size) {
Page<User> userPage = new Page<>(page, size);
IPage<User> users = userService.page(userPage);
return ResponseEntity.ok(users);
}
/**
* 更新用户
*
* @param id 用户ID
* @param user 用户信息
* @return 更新结果
*/
@PutMapping("/{id}")
@Operation(summary = "更新用户", description = "根据ID更新用户信息")
public ResponseEntity<Boolean> updateUser(
@Parameter(description = "用户ID", required = true) @PathVariable Long id,
@Parameter(description = "用户信息", required = true) @RequestBody User user) {
user.setId(id);
boolean updated = userService.updateUser(user);
return ResponseEntity.ok(updated);
}
/**
* 删除用户
*
* @param id 用户ID
* @return 删除结果
*/
@DeleteMapping("/{id}")
@Operation(summary = "删除用户", description = "根据ID删除用户")
public ResponseEntity<Boolean> deleteUser(
@Parameter(description = "用户ID", required = true) @PathVariable Long id) {
boolean deleted = userService.deleteUser(id);
return ResponseEntity.ok(deleted);
}
}
创建 MyBatis-Plus 分页插件配置类:
package com.example.druiddemo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MyBatis-Plus配置类
*
* @author ken
*/
@Configuration
public class MyBatisPlusConfig {
/**
* 配置分页插件
*
* @return MybatisPlusInterceptor
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件,指定数据库类型为MySQL
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
创建项目启动类:
package com.example.druiddemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
/**
* Druid示例项目启动类
*
* @author ken
*/
@SpringBootApplication
@MapperScan("com.example.druiddemo.mapper")
@OpenAPIDefinition(
info = @Info(
title = "Druid实战示例API",
version = "1.0",
description = "Druid连接池实战示例项目的API文档"
)
)
public class DruidDemoApplication {
public static void main(String[] args) {
SpringApplication.run(DruidDemoApplication.class, args);
}
}
启动项目后,可以通过以下方式测试接口:
Druid 提供了强大的监控功能,能够实时监控连接池状态、SQL 执行情况等关键指标。
除了内置监控,Druid 还支持自定义监控。例如,我们可以实现一个自定义的 StatFilter 来监控特定 SQL 的执行情况:
package com.example.druiddemo.filter;
import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.alibaba.druid.stat.DruidDataSourceStatManager;
import com.alibaba.druid.stat.JdbcSqlStat;
import lombok.extern.slf4j.Slf4j;
import java.sql.SQLException;
/**
* 自定义Druid监控过滤器
*
* @author ken
*/
@Slf4j
public class CustomDruidStatFilter extends StatFilter {
@Override
public void statementExecuteUpdateBefore(StatementProxy statement, String sql) throws SQLException {
log.info("执行更新SQL前: {}", sql);
super.statementExecuteUpdateBefore(statement, sql);
}
@Override
public void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) throws SQLException {
log.info("执行更新SQL后: {}, 影响行数: {}", sql, updateCount);
super.statementExecuteUpdateAfter(statement, sql, updateCount);
}
@Override
public void connectionCommitAfter(ConnectionProxy connection) throws SQLException {
log.info("事务提交");
// 打印当前连接池状态
printDataSourceStats();
super.connectionCommitAfter(connection);
}
/**
* 打印数据源状态
*/
private void printDataSourceStats() {
DruidDataSourceStatManager.getDataSourceInstances().forEach(dataSource -> {
log.info("数据源状态: 连接数={}, 活跃数={}, 等待数={}",
dataSource.getConnectCount(),
dataSource.getActiveCount(),
dataSource.getWaitThreadCount());
});
}
}
然后在配置类中注册这个过滤器:
package com.example.druiddemo.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.example.druiddemo.filter.CustomDruidStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Collections;
/**
* Druid配置类
*
* @author ken
*/
@Configuration
public class DruidConfig {
/**
* 配置数据源,添加自定义过滤器
*
* @return 数据源
*/
@Bean
@ConfigurationProperties("spring.datasource.druid")
public DataSource druidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
// 添加自定义监控过滤器
dataSource.setProxyFilters(Collections.singletonList(new CustomDruidStatFilter()));
return dataSource;
}
}
Druid 的 WallFilter 提供了 SQL 防火墙功能,能够有效防止 SQL 注入攻击。我们可以通过配置来限制特定类型的 SQL 操作:
spring:
datasource:
druid:
filter:
wall:
enabled: true
config:
drop-table-allow: false # 禁止删除表
alter-table-allow: false # 禁止修改表
truncate-allow: false # 禁止清空表
comment-allow: true # 允许注释
multi-statement-allow: false # 禁止多语句执行
# 限制特定表的操作
table-check: true
tables:
user:
select-allow: true
update-allow: true
insert-allow: true
delete-allow: false # 禁止删除用户表数据
Druid 的性能很大程度上取决于参数配置,以下是一些关键参数的调优建议:
调优是一个迭代过程,建议通过 Druid 的监控功能观察系统运行状态,逐步调整参数以达到最佳性能。
在分布式系统中,Druid 可以与分布式事务框架(如 Seata)配合使用,确保跨库事务的一致性。以下是一个简单的配置示例:
# Seata配置
seata:
enabled: true
application-id: druid-demo
tx-service-group: my_test_tx_group
service:
vgroup-mapping:
my_test_tx_group: default
grouplist:
default: 127.0.0.1:8091
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
在需要分布式事务的方法上添加 @GlobalTransactional 注解:
@GlobalTransactional(rollbackFor = Exception.class)
public boolean transfer(Long fromUserId, Long toUserId, BigDecimal amount) {
// 扣减转出用户余额
userAccountMapper.decreaseBalance(fromUserId, amount);
// 增加转入用户余额
userAccountMapper.increaseBalance(toUserId, amount);
return true;
}
连接泄露是指获取的连接没有正确关闭,导致连接池中的连接逐渐被耗尽。Druid 提供了检测和解决连接泄露的机制:
spring:
datasource:
druid:
remove-abandoned: true # 启用连接泄露检测
remove-abandoned-timeout: 300 # 泄露超时时间(秒)
log-abandoned: true # 记录泄露日志
慢 SQL 会严重影响系统性能,Druid 可以记录慢 SQL 并提供分析:
spring:
datasource:
druid:
filter:
stat:
log-slow-sql: true # 记录慢SQL
slow-sql-millis: 1000 # 慢SQL阈值(毫秒)
解决慢 SQL 的常见方法:
在高并发场景下,可能会出现连接池性能瓶颈,解决方案包括:
连接超时通常有以下几种原因及解决方案:
网络问题:检查网络连接,增加超时时间
spring:
datasource:
druid:
connectionProperties: connectTimeout=3000;socketTimeout=60000
数据库负载过高:优化数据库,增加资源
连接池配置不当:调整 maxActive、maxWait 等参数
连接失效:启用连接检测机制
spring:
datasource:
druid:
test-while-idle: true
validation-query: SELECT 1
Druid 作为一款优秀的数据库连接池,凭借其卓越的性能、丰富的功能和强大的监控能力,成为企业级应用的首选。本文从连接池的基本原理出发,对比了主流连接池的特点,详细介绍了 Druid 的优势和使用方法,并通过完整的实战案例展示了如何在 Spring Boot 项目中集成和使用 Druid。