在 Spring 框架中配置数据源(DataSource)主要有两种方式:
- 通过 Setter 注入配置数据源
- 通过 jdbc.properties 配置文件方式
本博文将使用 Druid 作为数据源,其在 Spring 项目中常见且高效。
Druid 被广泛认为是性能最佳的连接池之一,尤其在高并发场景下表现优异。它支持快速的连接获取和释放,优化了资源管理
🌱 1. 通过 Setter 注入配置 Druid 数据源
✅ 1.1 Maven 依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.24</version> <!-- 请根据项目需要选择版本 -->
</dependency>
✅ 1.2 XML 配置
修改 applicationContext.xml
文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- Druid 数据源配置 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mydb"/><property name="username" value="root"/><property name="password" value="root"/><!-- Druid 特有属性 --><property name="initialSize" value="5"/><property name="minIdle" value="5"/><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 1"/><property name="testWhileIdle" value="true"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/></bean><!-- JdbcTemplate 配置 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean></beans>
✅ 1.3 Java Config 配置 (推荐方式)
java">import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;@Configuration
public class DataSourceConfig {@Bean(destroyMethod = "close") // 指定关闭方法,释放资源public DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");dataSource.setUsername("root");dataSource.setPassword("root");// Druid 特有属性dataSource.setInitialSize(5);dataSource.setMinIdle(5);dataSource.setMaxActive(20);dataSource.setMaxWait(60000);dataSource.setTimeBetweenEvictionRunsMillis(60000);dataSource.setMinEvictableIdleTimeMillis(300000);dataSource.setValidationQuery("SELECT 1");dataSource.setTestWhileIdle(true);dataSource.setTestOnBorrow(false);dataSource.setTestOnReturn(false);return dataSource;}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);}
}
🗂️ 2. 通过 jdbc.properties 文件配置 Druid 数据源(推荐用于生产环境)
✅ 2.1 jdbc.properties 文件
# MySQL数据库配置
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root
jdbc.password=root
✅ 2.2 XML 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--1.开启命名空间--><!--2.使用 context 空间加载 properties 文件--><!-- <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/><context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/><context:property-placeholder location="*.properties" system-properties-mode="NEVER"/><context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/> --><!--加载最全的方式,除了本项目路径下的 properties,还可以加载 jar 包下的properties --><context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/><!--3.使用属性占位符 ${} 加载 properties 文件内容--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><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><bean id="userDao" class="com.alivinfer.dao.impl.UserDaoImpl"><property name="name" value="${jdbc.driver}"/></bean>
</beans>
💡 注意:
使用property-placeholder
标签需要引入以下命名空间:
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
✅ 2.3 Java Config 配置 (推荐方式)
java">import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;import javax.annotation.Resource;
import javax.sql.DataSource;@Configuration
@PropertySource("classpath:jdbc.properties") // 引入 properties 文件
public class DataSourceConfig {@Resourceprivate Environment env;@Bean(destroyMethod = "close")public DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(env.getProperty("jdbc.driver"));dataSource.setUrl(env.getProperty("jdbc.url"));dataSource.setUsername(env.getProperty("jdbc.username"));dataSource.setPassword(env.getProperty("jdbc.password"));dataSource.setInitialSize(Integer.parseInt(env.getProperty("druid.initialSize")));dataSource.setMinIdle(Integer.parseInt(env.getProperty("druid.minIdle")));dataSource.setMaxActive(Integer.parseInt(env.getProperty("druid.maxActive")));dataSource.setMaxWait(Long.parseLong(env.getProperty("druid.maxWait")));dataSource.setTimeBetweenEvictionRunsMillis(Long.parseLong(env.getProperty("druid.timeBetweenEvictionRunsMillis")));dataSource.setMinEvictableIdleTimeMillis(Long.parseLong(env.getProperty("druid.minEvictableIdleTimeMillis")));dataSource.setValidationQuery(env.getProperty("druid.validationQuery"));dataSource.setTestWhileIdle(Boolean.parseBoolean(env.getProperty("druid.testWhileIdle")));dataSource.setTestOnBorrow(Boolean.parseBoolean(env.getProperty("druid.testOnBorrow")));dataSource.setTestOnReturn(Boolean.parseBoolean(env.getProperty("druid.testOnReturn")));return dataSource;}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);}
}
✅ 测试代码
java">package com.alivinfer;import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.sql.DataSource;public class SpringTest {/*** 测试 xml 配置 druid 数据源*/@Testpublic void test() {// 获取 IoC 容器ApplicationContext applicationContext = newClassPathXmlApplicationContext("applicationContext.xml");// 测试 druid 数据源DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");System.out.println(dataSource);}}
🕶️ Druid 数据源优势
✅ 高效:相比 DriverManagerDataSource
,Druid 提供更高的并发性能和更好的连接池管理
✅ 稳定:支持 SQL 监控、慢 SQL 记录、防 SQL 注入、异常日志跟踪等特性
✅ 易用:通过配置文件实现灵活的参数调整,方便不同环境下的使用
💡 常见问题
-
Druid 日志过多:
- 在
jdbc.properties
中添加以下配置可减少不必要的日志:
druid.logAbandoned=false druid.removeAbandoned=false
- 在
-
com.mysql.cj.jdbc.Driver 找不到:
- 确保
mysql-connector-java
版本兼容,并检查URL
是否包含serverTimezone
参数:
jdbc.url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC
- 确保
-
数据库连接泄漏:
- 启用
removeAbandoned
功能,自动关闭超时未关闭的连接:
druid.removeAbandoned=true druid.removeAbandonedTimeout=1800
- 启用
📌 总结
配置方式 | 优点 | 缺点 | 推荐使用场景 |
---|---|---|---|
Setter 注入 (XML/Java Config) | 简单直观,便于理解 | 配置写在代码中,生产环境不推荐 | 小型项目、快速开发、临时测试 |
jdbc.properties 文件 (XML/Java Config) | 配置与代码解耦、支持环境切换、易于维护 | 需要维护额外的配置文件,但在中大型项目中是必要的 | 企业级项目、生产环境、灵活配置 |
推荐使用:
- 在 企业项目 和 生产环境 中,推荐使用 jdbc.properties 文件方式结合 Java Config,确保代码简洁、配置灵活,充分利用 Druid 的性能优势和监控功能