核心 DataSource Bean 定義模板
<bean id="dataSource" class="完整類名" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 連線池專屬屬性 -->
</bean>
五大主流實現對比
| 連線池 | 類別 | Maven 坐標 | 特點 | 推薦指數 |
| Spring 內建 | org.springframework.jdbc.datasource.DriverManagerDataSource | spring-jdbc | 非池化,每次 getConnection 新建連線,僅適合測試 | ⭐ |
| C3P0 | com.mchange.v2.c3p0.ComboPooledDataSource | c3p0:0.9.5.5 | 老牌、配置豐富、效能一般、維護較慢 | ⭐⭐ |
| DBCP 2 | org.apache.commons.dbcp2.BasicDataSource | commons-dbcp2:2.9.0 | Apache 專案、整合較好、效能中等 | ⭐⭐⭐ |
| Druid | com.alibaba.druid.pool.DruidDataSource | druid:1.2.20 | 國產之光、監控強大、SQL 防火牆、效能優異、阿里生產驗證 | ⭐⭐⭐⭐⭐ |
| HikariCP | com.zaxxer.hikari.HikariDataSource | HikariCP:5.0.1 | 極速、輕量、預設值合理、Spring Boot 2+ 預設選擇 | ⭐⭐⭐⭐⭐ |
完整配置範例
1. Druid(生產環境首選)
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 基礎池大小 -->
<property name="initialSize" value="5" />
<property name="minIdle" value="5" />
<property name="maxActive" value="20" />
<!-- 等待與超時 -->
<property name="maxWait" value="60000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- PSCache -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 監控與防火牆 -->
<property name="filters" value="stat,wall,log4j2" />
<property name="connectionProperties" value="druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000" />
</bean>
2. HikariCP(高併發首選)
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maximumPoolSize" value="20" />
<property name="minimumIdle" value="5" />
<property name="idleTimeout" value="300000" />
<property name="maxLifetime" value="1800000" />
<property name="connectionTimeout" value="30000" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="poolName" value="SpringHikariCP" />
</bean>
3. C3P0(舊專案維護)
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialPoolSize" value="5" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="acquireIncrement" value="3" />
<property name="maxIdleTime" value="300" />
<property name="preferredTestQuery" value="SELECT 1" />
<property name="testConnectionOnCheckout" value="true" />
</bean>
4. DBCP2(Tomcat/JNDI 環境常見)
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="5" />
<property name="maxTotal" value="20" />
<property name="maxIdle" value="10" />
<property name="minIdle" value="5" />
<property name="maxWaitMillis" value="30000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
</bean>
Spring Boot 自動配置策略
# application.yml
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource # 指定類型,否則按 classpath 自動檢測
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Taipei
username: root
password: 123456
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 300000
max-lifetime: 1800000
connection-timeout: 30000
pool-name: MyHikariCP
connection-test-query: SELECT 1
Spring Boot 2.x+ 預設 HikariCP,其次 Druid、Tomcat JDBC、DBCP2、C3P0。
關鍵調優參數解析
| 參數 | Druid | HikariCP | 建議值 | 說明 |
| 最大連線數 | maxActive | maximumPoolSize | CPU核心數 * 2 + 有效磁碟數 | OLTP 約 20-50,避免資料庫連線耗盡 |
| 最小閒置 | minIdle | minimumIdle | 同 maxActive 或略小 | 減少連線建立延遲,冷啟動更快 |
| 連線驗證 | validationQuery + testWhileIdle | connectionTestQuery | SELECT 1 (MySQL) | 防止資料庫斷開導致無效連線 |
| 閒置回收 | minEvictableIdleTimeMillis | idleTimeout | 5-10 分鐘 | 釋放長期未用連線 |
| 最大壽命 | maxEvictableIdleTimeMillis (間接) | maxLifetime | 30 分鐘 | 防止連線過舊導致資料庫端斷開 |
| PSCache | poolPreparedStatements | 不支援 (內建優化) | true / 20 | 減少 PreparedStatement 重複編譯 |
多資料源配置模式
@Configuration
@MapperScan(basePackages = "com.app.db1.mapper", sqlSessionFactoryRef = "db1SqlSessionFactory")
public class Db1Config {
@Bean @ConfigurationProperties("spring.datasource.db1")
DataSource db1DataSource() { return DataSourceBuilder.create().build(); }
@Bean
SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource ds) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/*.xml"));
return bean.getObject();
}
}
// 同理定義 Db2Config,使用 @Primary 標記預設資料源
監控與運維
- Druid:
/druid/index.html 即時 SQL 監控、慢查詢、連線池狀態、防火牆攔截日誌。
- HikariCP:JMX MBeans、Micrometer/Prometheus 指標(
hikaricp.connections.active、hikaricp.connections.idle、hikaricp.connections.pending)。
- 通用:啟用
log4j2.logger.org.apache.commons.dbcp2=DEBUG 或對應池的 DEBUG 日誌排查洩漏。
避坑指南
- 資料庫連線屬性名稱差異:
url vs jdbcUrl,username vs user,務必對照類別定義。
- MySQL 8+ 需
useSSL=false、serverTimezone=Asia/Taipei、allowPublicKeyRetrieval=true。
- 連線池未正確關閉導致資源洩漏:確保
destroy-method="close" 或 @PreDestroy。
- 事務管理器必須引用正確的 DataSource Bean:
@Bean PlatformTransactionManager txManager(@Qualifier("db1DataSource") DataSource ds)。
- 生產環境禁用 Spring 內建 DriverManagerDataSource。