JDBC连接池

JDBC连接池


一、连接池基本概念

1. 什么是连接池

连接池是创建和管理数据库连接的缓冲池技术,它预先建立一定数量的数据库连接,当应用程序需要时从池中获取连接,使用完毕后归还给池而不是直接关闭。

2. 为什么需要连接池

  • 资源重用:避免频繁创建和销毁连接的开销
  • 性能提升:减少连接建立时间,提高响应速度
  • 连接管理:统一管理连接,避免连接泄漏
  • 系统稳定:控制最大连接数,防止数据库过载

二、主流JDBC连接池

1. HikariCP

特点

  • 目前性能最好的连接池
  • 代码精简(约130kb)
  • 零依赖
  • 支持JMX监控

Maven依赖

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.1</version>
</dependency>

2. Druid

特点

  • 阿里巴巴开源项目
  • 功能全面(监控、加密等)
  • 对MySQL特别优化
  • 提供强大的监控统计功能

Maven依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>

3. Apache DBCP2

特点

  • Apache Commons项目
  • 成熟稳定
  • 功能全面
  • 适合传统企业应用

Maven依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.9.0</version>
</dependency>

4. C3P0

特点

  • 老牌连接池
  • 稳定性好
  • 支持JDBC3和JDBC2
  • 配置相对复杂

Maven依赖

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.5</version>
</dependency>

三、连接池配置详解

1. 核心配置参数

参数说明推荐值
initialSize初始连接数5-10
minIdle最小空闲连接与initialSize相同
maxActive/maximumPoolSize最大活动连接数20-100(根据系统负载调整)
maxWait获取连接最大等待时间(ms)3000
timeBetweenEvictionRunsMillis检查空闲连接的间隔时间(ms)60000
minEvictableIdleTimeMillis连接最小空闲时间(ms)300000
validationQuery连接有效性测试SQLSELECT 1
testWhileIdle空闲时是否测试连接true
testOnBorrow获取连接时是否测试false
testOnReturn归还连接时是否测试false

2. HikariCP配置示例

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("username");
config.setPassword("password");
config.setDriverClassName("com.mysql.jdbc.Driver");

// 连接池配置
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(3000);
config.setIdleTimeout(60000);
config.setMaxLifetime(1800000);
config.setPoolName("MyHikariCP");

// MySQL优化参数
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

HikariDataSource dataSource = new HikariDataSource(config);

3. Druid配置示例

DruidDataSource dataSource = new DruidDataSource();

// 基本配置
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");

// 连接池配置
dataSource.setInitialSize(5);
dataSource.setMinIdle(5);
dataSource.setMaxActive(20);
dataSource.setMaxWait(3000);
dataSource.setTimeBetweenEvictionRunsMillis(60000);
dataSource.setMinEvictableIdleTimeMillis(300000);

// 监控配置
dataSource.setFilters("stat,wall");
dataSource.setUseGlobalDataSourceStat(true);

// 连接测试
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);

四、连接池使用模式

1. 基本使用模式

// 获取数据源
DataSource dataSource = getDataSource();

try (Connection conn = dataSource.getConnection();
     PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users");
     ResultSet rs = pstmt.executeQuery()) {
     
    while (rs.next()) {
        // 处理结果
    }
} catch (SQLException e) {
    // 异常处理
}

2. 使用连接池的工具类

public class JdbcUtils {
    private static DataSource dataSource;
    
    static {
        // 初始化连接池
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        // 其他配置...
        dataSource = new HikariDataSource(config);
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
            if (conn != null) conn.close(); // 实际是归还给连接池
        } catch (SQLException e) {
            // 日志记录
        }
    }
}

3. 与Spring集成

@Configuration
public class DataSourceConfig {
    
    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        // 其他配置...
        return new HikariDataSource(config);
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

五、连接池监控与管理

1. HikariCP监控

HikariDataSource dataSource = (HikariDataSource) context.getBean("dataSource");

// 获取连接池状态
HikariPoolMXBean poolMXBean = dataSource.getHikariPoolMXBean();
System.out.println("活动连接: " + poolMXBean.getActiveConnections());
System.out.println("空闲连接: " + poolMXBean.getIdleConnections());
System.out.println("等待线程: " + poolMXBean.getThreadsAwaitingConnection());

2. Druid监控

// 配置Web监控
@Bean
public ServletRegistrationBean<StatViewServlet> druidStatViewServlet() {
    ServletRegistrationBean<StatViewServlet> reg = new ServletRegistrationBean<>();
    reg.setServlet(new StatViewServlet());
    reg.addUrlMappings("/druid/*");
    // 白名单
    reg.addInitParameter("allow", "127.0.0.1");
    // 黑名单
    reg.addInitParameter("deny", "");
    // 登录查看信息的账号密码
    reg.addInitParameter("loginUsername", "admin");
    reg.addInitParameter("loginPassword", "admin");
    return reg;
}

// 配置过滤器
@Bean
public FilterRegistrationBean<WebStatFilter> druidWebStatFilter() {
    FilterRegistrationBean<WebStatFilter> reg = new FilterRegistrationBean<>();
    reg.setFilter(new WebStatFilter());
    reg.addUrlPatterns("/*");
    reg.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
    return reg;
}

六、连接池最佳实践

  1. 选择合适的连接池:新项目推荐HikariCP,需要监控选Druid

  2. 合理配置连接数

    • 计算公式:连接数 = (核心数 * 2) + 有效磁盘数
    • 对于8核系统:建议连接数在20-30之间
  3. 连接泄漏检测

    // HikariCP
    config.setLeakDetectionThreshold(60000); // 60秒
    
    // Druid
    dataSource.setRemoveAbandoned(true);
    dataSource.setRemoveAbandonedTimeout(60); // 60秒
    dataSource.setLogAbandoned(true);
    
  4. 生产环境建议

    • 开启连接池JMX监控
    • 定期检查连接池状态
    • 设置合理的超时时间
    • 配置连接有效性测试
  5. 避免常见错误

    • 忘记关闭连接(使用try-with-resources)
    • 在循环中创建连接池
    • 配置过大的maxActive值
    • 不配置validationQuery

七、连接池性能优化

  1. 预处理语句缓存

    // HikariCP
    config.addDataSourceProperty("cachePrepStmts", "true");
    config.addDataSourceProperty("prepStmtCacheSize", "250");
    config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    
    // Druid
    dataSource.setPoolPreparedStatements(true);
    dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
    
  2. 连接超时设置

    • connectionTimeout:获取连接超时(推荐1-5秒)
    • idleTimeout:空闲连接超时(推荐60秒)
    • maxLifetime:连接最大生命周期(推荐30分钟)
  3. JDBC驱动参数优化

    // MySQL
    config.addDataSourceProperty("useServerPrepStmts", "true");
    config.addDataSourceProperty("useLocalSessionState", "true");
    config.addDataSourceProperty("rewriteBatchedStatements", "true");
    config.addDataSourceProperty("cacheResultSetMetadata", "true");
    config.addDataSourceProperty("cacheServerConfiguration", "true");
    config.addDataSourceProperty("elideSetAutoCommits", "true");
    config.addDataSourceProperty("maintainTimeStats", "false");
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值