详解 Spring 配置数据源的两种方式

embedded/2025/2/28 15:32:14/

在 Spring 框架中配置数据源(DataSource)主要有两种方式:

  1. 通过 Setter 注入配置数据源
  2. 通过 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 注入、异常日志跟踪等特性
✅ 易用:通过配置文件实现灵活的参数调整,方便不同环境下的使用


💡 常见问题

  1. Druid 日志过多

    • jdbc.properties 中添加以下配置可减少不必要的日志:
    druid.logAbandoned=false
    druid.removeAbandoned=false
    
  2. com.mysql.cj.jdbc.Driver 找不到

    • 确保 mysql-connector-java 版本兼容,并检查 URL 是否包含 serverTimezone 参数:
    jdbc.url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC
    
  3. 数据库连接泄漏

    • 启用 removeAbandoned 功能,自动关闭超时未关闭的连接:
    druid.removeAbandoned=true
    druid.removeAbandonedTimeout=1800
    

📌 总结

配置方式优点缺点推荐使用场景
Setter 注入 (XML/Java Config)简单直观,便于理解配置写在代码中,生产环境不推荐小型项目、快速开发、临时测试
jdbc.properties 文件 (XML/Java Config)配置与代码解耦、支持环境切换、易于维护需要维护额外的配置文件,但在中大型项目中是必要的企业级项目、生产环境、灵活配置

推荐使用

  • 企业项目生产环境 中,推荐使用 jdbc.properties 文件方式结合 Java Config,确保代码简洁、配置灵活,充分利用 Druid 的性能优势和监控功能

http://www.ppmy.cn/embedded/168819.html

相关文章

【随手笔记】RTthread软件占用资源记录

记录某项目开发初期的笔记 嵌入式软件不关心占用硬件资源是不合适的 大多数开发的场景 受限于成本考虑 MCU的 RAM和ROM有限 富余的只能说明 有水分或者钱多 省1块 1万就是1万 10万就是 10万 钱是公司的 困难是自己的 标准来说 开发难度优先级很低 因为开发人员只是电脑工具 标…

阿里开源正式开园文生视频、图生视频模型-通义万相 WanX2.1

简介 发布时间与背景 通义万相 Wan2.1 模型于 2025年1月 发布&#xff0c;并迅速登顶视频生成领域权威评测 Vbench 的榜首&#xff0c;超越了包括 Sora、HunyuanVideo、Minimax 等国内外知名模型&#xff0c;并于这周开源。它是阿里云在 AI 视频生成领域的最新成果&#xff0…

C++17中方便文件操作的工具包filesystem-250227

对文件的删除操作用iostream包中的工具不容易实现而使用C17中的filesystem包中工具就可以轻松实现 #include <iostream> #include <filesystem>namespace fs std::filesystem; int main() {std::string path "./workdir";for (auto p : fs::directory…

如何免费使用稳定的deepseek

0、背景&#xff1a; 在AI辅助工作中&#xff0c;除了使用cursor做编程外&#xff0c;使用deepseek R1进行问题分析、数据分析、代码分析效果非常好。现在我经常会去拿行业信息、遇到的问题等去咨询R1&#xff0c;也给了自己不少启示。但是由于官网稳定性很差&#xff0c;很多…

测试用例详解

一、通用测试用例八要素   1、用例编号&#xff1b;    2、测试项目&#xff1b;   3、测试标题&#xff1b; 4、重要级别&#xff1b;    5、预置条件&#xff1b;    6、测试输入&#xff1b;    7、操作步骤&#xff1b;    8、预期输出 二、具体分析通…

C++ Primer 成员访问运算符

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

游戏引擎学习第125天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾并为今天的内容做准备。 昨天&#xff0c;当我们离开时&#xff0c;工作队列已经完成了基本的功能。这个队列虽然简单&#xff0c;但它能够执行任务&#xff0c;并且我们已经为各种操作编写了测试。字符串也能够正常推送到队…

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议&#xff0c;其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者的通信流程、安全机制及核心差异。 一、HTTP的通信机制 先来看看HTTP是什么吧。 HTTP基于TCP/IP协议栈&#xff0c;采用经典客户端-服务…