Spring Boot中用application.properties配置多个JdbcTemplate运行报错求助
嘿,我猜你遇到的应该是NoUniqueBeanDefinitionException这类异常吧?毕竟Spring Boot默认会自动配置一个JdbcTemplate,但当你有多个数据源时,容器里存在多个DataSource实例,Spring根本不知道该选哪一个注入到自动配置的JdbcTemplate里,这不就冲突报错了嘛!下面给你一套完整的解决方案,一步步来:
第一步:先把配置文件补全并规范
你提供的Oracle数据源配置没写完,首先得把驱动类加上,另外建议给两个数据源加明确的前缀区分,避免混淆,调整后的application.properties如下:
# MySQL 数据源配置 spring.datasource.mysql.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.mysql.url=jdbc:mysql://localhost:3306/ccm_new?useSSL=false&serverTimezone=UTC spring.datasource.mysql.username=test spring.datasource.mysql.password=test # Oracle 数据源配置 spring.datasource.oracle.driver-class-name=oracle.jdbc.OracleDriver spring.datasource.oracle.url=jdbc:oracle:thin:@localhost:1521:mastera spring.datasource.oracle.username=test spring.datasource.oracle.password=test
小贴士:MySQL 8+版本推荐用
com.mysql.cj.jdbc.Driver,如果是老版本MySQL,换回com.mysql.jdbc.Driver就行。
第二步:手动配置两个数据源Bean
Spring Boot的自动配置在这里帮倒忙了,我们得自己定义两个DataSource实例,还可以给其中一个标记@Primary(作为默认数据源,不需要的话也可以去掉,但后续注入必须明确指定名称):
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class MultipleDataSourceConfig { // MySQL数据源 @Primary @Bean(name = "mysqlDataSource") @ConfigurationProperties(prefix = "spring.datasource.mysql") public DataSource mysqlDataSource() { return DataSourceBuilder.create().build(); } // Oracle数据源 @Bean(name = "oracleDataSource") @ConfigurationProperties(prefix = "spring.datasource.oracle") public DataSource oracleDataSource() { return DataSourceBuilder.create().build(); } }
@ConfigurationProperties会自动把配置文件中对应前缀的属性绑定到DataSource上,省得我们手动一个个set。
第三步:为每个数据源创建专属JdbcTemplate
现在有了两个DataSource,我们要给每个都配一个JdbcTemplate,这样容器里就有两个明确的JdbcTemplate Bean,不会再冲突了:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class MultipleJdbcTemplateConfig { // MySQL对应的JdbcTemplate @Primary @Bean(name = "mysqlJdbcTemplate") public JdbcTemplate mysqlJdbcTemplate(DataSource mysqlDataSource) { return new JdbcTemplate(mysqlDataSource); } // Oracle对应的JdbcTemplate @Bean(name = "oracleJdbcTemplate") public JdbcTemplate oracleJdbcTemplate(DataSource oracleDataSource) { return new JdbcTemplate(oracleDataSource); } }
这里的方法参数会自动匹配我们之前定义的同名DataSource Bean,Spring的依赖注入会按名称精准匹配,很省心。
第四步:在业务代码中指定使用哪个JdbcTemplate
最后一步,在需要用的地方,通过@Qualifier注解明确指定要注入的JdbcTemplate名称,避免Spring犯选择困难症:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; @Service public class DataService { private final JdbcTemplate mysqlJdbcTemplate; private final JdbcTemplate oracleJdbcTemplate; // 推荐用构造方法注入,比字段注入更安全 @Autowired public DataService(@Qualifier("mysqlJdbcTemplate") JdbcTemplate mysqlJdbcTemplate, @Qualifier("oracleJdbcTemplate") JdbcTemplate oracleJdbcTemplate) { this.mysqlJdbcTemplate = mysqlJdbcTemplate; this.oracleJdbcTemplate = oracleJdbcTemplate; } // 示例:查询MySQL数据 public void fetchMysqlData() { String sql = "SELECT * FROM your_mysql_table"; mysqlJdbcTemplate.query(sql, (rs, rowNum) -> { // 这里处理结果集,比如封装成实体类 return null; }); } // 示例:查询Oracle数据 public void fetchOracleData() { String sql = "SELECT * FROM your_oracle_table"; oracleJdbcTemplate.query(sql, (rs, rowNum) -> { // 处理Oracle查询结果 return null; }); } }
踩坑小贴士
- 如果还是报
NoUniqueBeanDefinitionException,那可能是Spring Boot的自动配置还在生效,你可以在启动类上加上@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class}),彻底禁用自动配置,只使用我们手动定义的Bean。 - 检查配置文件的前缀和
@ConfigurationProperties里的prefix是否完全一致,比如你原来用的是spring.oracledatasource,那prefix就要写spring.oracledatasource,别写错字母! - 确保Oracle驱动依赖已经加到项目里了,Maven的话可以加这个依赖:
<dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>21.13.0.0</version> </dependency>
内容的提问来源于stack exchange,提问作者Vishal Monga

