从SpringBoot项目报错中学习:为何`url`和`jdbc-url`让我焦头烂额

从报错中学习:为何urljdbc-url让我焦头烂额

踩坑记录:最近有一个项目需要分库分表,我在测试多数据源操作数据库的时候,由于对连接池和数据源配置存在盲区,报错频繁报错jdbcUrl is required with driverClassName.。经过排查,发现是连接池属性配置错误。本文还原完整排查过程。


一、诡异报错现场

在这里插入图片描述

错误堆栈关键片段

java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.

	at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:1022)
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109)
	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159)
	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117)
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:376)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:431)
	at cn.com.h8k.onecoupon.engine.UserCouponTableCreateTest.createCouponTemplate(UserCouponTableCreateTest.java:64)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)

最迷惑的配置:

#错误配置!同时出现jdbc-url和url会怎样?
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    jdbc-url: jdbc:mysql://localhost:3306/real_db
    username: root
    password: 123456

二、为什么不能混用?

  1. HikariCP 的潜规则
    1. 底层逻辑:Spring Boot优先识别jdbc-url
    2. 冲突后果:url会被自动忽略
    3. 致命陷阱:如果同时配置HikariCP&Druid
      type: com.alibaba.druid.pool.DruidDataSource # 实际用的是Druid!
      jdbc-url: ... # Druid不识别这个字段!
      
  2. 不同连接池的命名差异
HikariCPDruidTomcat JDBC
连接地址jdbc-urlurlurl
超时配置connection-timeoutmaxWaitmax-wait
  1. SpringBoot版本适配
版本默认连接池
1.xTomcat Pool
2.x以后包括3.xHikariCP

三、正确配置模板

  1. 使用HikariCP连接池的数据库配置
spring:
  datasource:
    # 核心配置(必须用jdbc-url)
    jdbc-url: "jdbc:mysql://${MYSQL_HOST:localhost}:3306/core_db?characterEncoding=UTF-8"
    username: app_user
    password: ${DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver
    
    # Hikari专属配置
    hikari:
      pool-name: OrderAPIPool
      maximum-pool-size: 20
      connection-timeout: 1000
  1. 使用Druid连接池的配置
spring:
  datasource:
    # 此处必须用url!
    url: "jdbc:mysql://db-prod.example.com:3306/finance?useSSL=true"
    username: dr_admin
    password: ${PROD_DB_PWD}
    driver-class-name: com.mysql.cj.jdbc.Driver
    
    # Druid专属配置
    druid:
      initial-size: 5
      max-active: 20
      filters: stat,wall # 启用防火墙

四、高频踩坑场景

场景1:直接复制代码导致冲突

# 错误的示范(来自某网课代码)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test # 被下面覆盖
    jdbc-url: jdbc:mysql://localhost:3306/real # Hikari优先使用
    type: com.alibaba.druid.pool.DruidDataSource # Druid不认识jdbc-url!
#现象:Druid无法获取连接地址,启动时报URL未配置

场景2:多数据源配置混淆

datasource:
  order:
    jdbc-url: ... # 正确
  user:
    url: ... # 错误!应该保持命名统一
#后果:第二个数据源初始化失败

四、多数据源架构实现(生产配置范例)

配置规范:

  1. 使用独立命名空间区分数据源
  2. 主库标记@Primary注解
  3. 配置隔离:事务管理器与JPA实体分开绑定
# 读写主库
spring.datasource.primary.jdbc-url=jdbc:mysql://master-db:3306/core
spring.datasource.primary.hikari.connection-init-sql=SET NAMES utf8mb4

# 报表从库 
spring.datasource.replica.jdbc-url=jdbc:mysql://replica-db:3306/report
spring.datasource.replica.hikari.read-only=true

核心Java配置段

@Configuration
@EnableTransactionManagement
public class MultiDataSourceConfig {

    @Primary
    @Bean(name = "primaryDS")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();  // Hikari连接池写这个
        return DruidDataSourceBuilder.create().build();  // Druid连接池写这个
    }

    @Bean(name = "replicaDS")
    @ConfigurationProperties(prefix = "spring.datasource.replica")
    public DataSource replicaDataSource() {
        return DataSourceBuilder.create().build();  // Hikari连接池写这个
        return DruidDataSourceBuilder.create().build();  // Druid连接池写这个
    }
}
### 解决 Spring Boot 项目启动时因未配置 DataSource URL 导致的报错问题 Spring Boot 在启动时会尝试自动配置 `DataSource`,如果未正确指定 `url` 属性或缺少相关依赖,则会出现以下错误: ``` Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. ``` 以下是解决此问题的详细方法。 #### 1. 配置正确的 JDBC URL 确保在 `application.properties` 或 `application.yml` 文件中正确配置了 `spring.datasource.url` 属性。例如,对于 MySQL 数据库,可以这样配置[^1]: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=secret ``` 如果使用 YAML 格式,则可以这样配置[^2]: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC username: root password: secret ``` #### 2. 确保数据库驱动程序已添加到项目中 如果没有将数据库驱动程序添加到项目的依赖项中,Spring Boot 将无法找到合适的驱动类。例如,对于 MySQL 数据库,需要在 `pom.xml` 中添加以下依赖项[^3]: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> ``` #### 3. 激活特定的配置文件 如果数据源配置位于特定的配置文件中(如 `application-dev.properties`),但未激活相应的配置文件,则可能导致 Spring Boot 无法加载这些配置。可以通过以下方式激活配置文件[^4]: - 在 `application.properties` 中添加: ```properties spring.profiles.active=dev ``` - 或者通过命令行参数激活: ```bash java -jar myapp.jar --spring.profiles.active=dev ``` #### 4. 禁用数据源自动配置 如果项目不需要使用数据库,可以通过禁用数据源自动配置来避免此错误。在 `application.properties` 中添加以下内容[^5]: ```properties spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration ``` 或者在 `application.yml` 中配置为: ```yaml spring: autoconfigure: exclude: - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration ``` #### 5. 使用嵌入式数据库 如果项目需要一个简单的嵌入式数据库(如 H2、HSQL 或 Derby),可以将相应的数据库驱动程序添加到项目的依赖项中,并确保其位于类路径上。例如,对于 H2 数据库,可以在 `pom.xml` 中添加以下依赖项: ```xml <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> ``` 然后,在 `application.properties` 中配置如下: ```properties spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.h2.console.enabled=true ``` #### 6. 常见问题排查 - **检查拼写错误**:确保 `spring.datasource.url` 属性名称值没有拼写错误。 - **验证数据库连接**:确保数据库服务正在运行,并且提供的用户名密码正确。 - **确认依赖项版本兼容性**:确保使用的数据库驱动程序与 Spring Boot 版本兼容。 ### 示例代码 以下是一个完整的 Spring Boot 应用程序示例,展示了如何正确配置数据源并执行简单的查询: ```java package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.jdbc.core.JdbcTemplate; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } @RestController class DatabaseController { private final JdbcTemplate jdbcTemplate; public DatabaseController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @GetMapping("/users") public String getUsers() { return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users", Integer.class).toString(); } } ``` 上述代码中,`JdbcTemplate` 用于执行 SQL 查询,`/users` 接口返回数据库中 `users` 表的记录数[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Honyelchak

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值