| 方式 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| JNDI | 生產環境、應用服務器管理連接池 | 統一資源管理、支援集群、安全隔離 | 依賴容器配置、開發調試稍繁 |
| 第三方連接池 (DBCP/C3P0/HikariCP) | 獨立部署、Spring 管理池 | 配置靈活、性能可控、無容器依賴 | 需自行調優參數 |
| DriverManagerDataSource | 測試、極簡場景 | 零依賴、配置最簡 | 無連接池,生產禁用 |
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/myDataSource"/>
<!-- 可選:資源引用為真,預期類型 -->
<property name="resourceRef" value="true"/>
<property name="expectedType" value="javax.sql.DataSource"/>
</bean>
<Resource name="jdbc/myDataSource"
auth="Container"
type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="app_user" password="secret"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/app_db?useSSL=false"
validationQuery="SELECT 1"
testOnBorrow="true"/>
<resource-ref>
<res-ref-name>jdbc/myDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/app_db"/>
<property name="username" value="app_user"/>
<property name="password" value="secret"/>
<!-- 核心池參數 -->
<property name="maxActive" value="100"/>
<property name="maxIdle" value="30"/>
<property name="maxWait" value="10000"/>
<property name="defaultAutoCommit" value="false"/>
<!-- 連接驗證 -->
<property name="validationQuery" value="SELECT 1"/>
<property name="testOnBorrow" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/app_db"/>
<property name="user" value="app_user"/>
<property name="password" value="secret"/>
<property name="maxPoolSize" value="100"/>
<property name="minPoolSize" value="10"/>
<property name="maxIdleTime" value="300"/>
<property name="preferredTestQuery" value="SELECT 1"/>
<property name="testConnectionOnCheckout" value="true"/>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/app_db"/>
<property name="username" value="app_user"/>
<property name="password" value="secret"/>
<property name="maximumPoolSize" value="20"/>
<property name="minimumIdle" value="5"/>
<property name="connectionTimeout" value="30000"/>
<property name="idleTimeout" value="600000"/>
<property name="maxLifetime" value="1800000"/>
<property name="connectionTestQuery" value="SELECT 1"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/app_db"/>
<property name="username" value="app_user"/>
<property name="password" value="secret"/>
</bean>
警告:每次
getConnection()都物理建立新連接,無池化,高併發下極其低效且易耗盡數據庫連接數。生產環境嚴禁使用。
| 參數 | 含義 | 建議起始值 |
|---|---|---|
| maxActive / maximumPoolSize | 最大連接數 | CPU 核心數 * 2 + 磁盤數 (或 20-50) |
| maxIdle / minimumIdle | 空閒保持數 | 10-20 |
| maxWait / connectionTimeout | 獲取連接超時(ms) | 5000-10000 |
| validationQuery / connectionTestQuery | 驗證 SQL | SELECT 1 (MySQL), SELECT 1 FROM DUAL (Oracle) |
| testOnBorrow | 借用時驗證 | true |
| testWhileIdle / idleTimeout | 空閒驗證/回收 | true / 10-30 分鐘 |
| removeAbandoned / maxLifetime | 洩漏回收 | true / 30 分鐘 |
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
選型原則:生產首選 HikariCP(性能最優、參數最少)、容器管理選 JNDI、舊專案維護用 DBCP/C3P0。DataSource 單例化,統一交給 Spring 管理生命週期。