使用jdbcTemplate查詢數據庫
springboot2版本項目中已經整合了mybatis框架,yml文件中配置好了數據源, 現在想再使用jdbcTemplate查詢另外一個數據庫,需要怎么配置

# 這是你現有的MyBatis數據源配置(假設使用默認前綴)
spring:
datasource:
url: jdbc:mysql://localhost:3306/main_db
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
# 新增的第二個數據源配置
datasource:
secondary:
jdbc-url: jdbc:mysql://localhost:3306/another_db # 注意這里使用jdbc-url而非url:cite[5]:cite[10]
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
# 可以根據需要配置連接池參數,例如HikariCP:
hikari:
maximum-pool-size: 10
minimum-idle: 2
注意:第二個數據源的URL配置,建議使用 jdbc-url 而不是 url。這是因為Spring Boot在自動配置多個數據源時可能會產生沖突,明確指定 jdbc-url 可以避免 "jdbcUrl is required with driverClassName" 的錯誤
編寫Java配置類
新建一個Java配置類(例如 JdbcTemplateConfig),用于創建第二個數據源的 DataSource Bean 和 JdbcTemplate Bean。
import org.springframework.beans.factory.annotation.Qualifier; 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 org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class JdbcTemplateConfig { /** * 配置第二個數據源 * 使用@ConfigurationProperties注解綁定配置文件中"spring.datasource.secondary"開頭的屬性 */ @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } /** * 創建第二個JdbcTemplate,并注入名為"secondaryDataSource"的數據源。 * 使用@Qualifier注解明確指定要注入的Bean名稱。 */ @Bean(name = "secondaryJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
關鍵點說明:
-
@Bean(name = "secondaryDataSource"): 為Bean定義一個名稱,便于后續注入時區分。 -
@ConfigurationProperties(prefix = "spring.datasource.secondary"): 告訴Spring將配置文件中以spring.datasource.secondary為前綴的屬性映射到這個DataSource的所有屬性上。 -
@Qualifier("secondaryDataSource"): 當注入DataSource時,通過名稱明確指定要注入的是我們剛剛定義的第二個數據源Bean,而不是MyBatis使用的那個默認數據源
在Service中使用第二個JdbcTemplate
在你的Service類中,使用 @Autowired 和 @Qualifier 注解注入指定的 JdbcTemplate Bean。
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; import java.util.List; import java.util.Map; @Service public class YourService { // 注入第二個JdbcTemplate @Autowired @Qualifier("secondaryJdbcTemplate") // 指定注入名為"secondaryJdbcTemplate"的Bean private JdbcTemplate secondaryJdbcTemplate; public List<Map<String, Object>> queryFromOtherDatabase() { String sql = "SELECT * FROM some_table"; // 使用secondaryJdbcTemplate執行查詢,操作的就是另一個數據庫 return secondaryJdbcTemplate.queryForList(sql); } }
重要的注意事項
-
事務管理:需要特別注意事務問題。如果你在使用了
@Transactional注解的方法中操作多個數據源,默認的事務管理器可能只管理其中一個數據源的事務。你需要為每個數據源配置獨立的PlatformTransactionManagerBean,并在@Transactional注解中通過transactionManager屬性指定使用哪個事務管理器。例如:@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
然后在使用時:
@Transactional(transactionManager = "secondaryTransactionManager") // 指定事務管理器
public void updateInSecondaryDatabase() {
// ... 使用secondaryJdbcTemplate執行更新操作
}
對于需要跨數據源的真正分布式事務,需要考慮使用JTA解決方案,但這會復雜得多
<!-- MyBatis Spring Boot Starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
如果遇到數據源錯亂問題,參考????
?? 原因分析與解決方案
1. 數據源(DataSource)Bean的注入問題
Spring Boot的自動配置在遇到多個DataSource Bean時,如果未明確指定,可能會注入錯誤的Bean。
-
原因:你可能配置了多個
DataSourceBean(例如一個給MyBatis,一個給JdbcTemplate),但沒有明確地通過@Primary注解指定哪個是默認數據源,或者沒有在注入時通過@Qualifier注解按名稱(Bean Name)進行區分。這會導致Spring自動注入時發生混亂。 -
解決方案:確保每個
DataSourceBean都有唯一的名稱,并且為MyBatis使用的數據源設置@Primary注解(如果你的MyBatis期望使用主數據源)。同時,在注入時使用@Qualifier明確指定。
@Configuration public class DataSourceConfig { // 為MyBatis配置主數據源(primary) @Bean(name = "mybatisDataSource") @Primary // 關鍵:標記為默認數據源,MyBatis通常會使用默認的DataSource @ConfigurationProperties(prefix = "spring.datasource.mybatis") public DataSource mybatisDataSource() { return DataSourceBuilder.create().build(); } // 為JdbcTemplate配置另一個數據源 @Bean(name = "jdbcTemplateDataSource") @ConfigurationProperties(prefix = "spring.datasource.jdbctemplate") public DataSource jdbcTemplateDataSource() { return DataSourceBuilder.create().build(); } }
然后在配置JdbcTemplate時,明確指定使用哪個數據源:
@Bean public JdbcTemplate jdbcTemplate(@Qualifier("jdbcTemplateDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); }
MyBatis(尤其是通過mybatis-spring-boot-starter自動配置時)通常會自動使用標記了@Primary的DataSource。
2. MyBatis配置未正確關聯指定數據源
如果你為MyBatis自定義了配置,需要確保其使用的SqlSessionFactoryBean關聯到了正確的DataSource Bean。
-
原因:自定義的
SqlSessionFactoryBean可能沒有注入你希望它使用的DataSource。 -
解決方案:在創建
SqlSessionFactoryBean時,通過@Qualifier注入為MyBatis準備的特定數據源。
@Configuration @MapperScan(basePackages = "com.example.mapper", sqlSessionFactoryRef = "mybatisSqlSessionFactory") public class MyBatisConfig { @Bean(name = "mybatisSqlSessionFactory") public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("mybatisDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); // 關聯MyBatis專用的數據源 // 其他MyBatis配置(如mapper.xml位置等) return sessionFactory; } }
3. 事務管理器(TransactionManager)沖突
Spring的事務管理也需要知道操作哪個數據源。
-
原因:如果只配置了一個全局的
PlatformTransactionManager,它可能綁定到了錯誤的數據源上。 -
解決方案:為不同的數據源配置各自的事務管理器,并在使用
@Transactional注解時根據需要指定事務管理器(但通常查詢操作不涉及事務,此問題影響較小)。
@Bean(name = "mybatisTransactionManager") @Primary public PlatformTransactionManager mybatisTransactionManager(@Qualifier("mybatisDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "jdbcTemplateTransactionManager") public PlatformTransactionManager jdbcTemplateTransactionManager(@Qualifier("jdbcTemplateDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); }
4. 配置文件(application.yml)問題
確保你的配置文件中的多數據源配置前綴正確,并且沒有相互覆蓋。
spring:
datasource:
# MyBatis 使用的數據源配置
mybatis:
jdbc-url: jdbc:mysql://localhost:3306/db_mybatis
username: user_mybatis
password: pass_mybatis
driver-class-name: com.mysql.cj.jdbc.Driver
# JdbcTemplate 使用的數據源配置
jdbctemplate:
jdbc-url: jdbc:mysql://localhost:3306/db_jtemplate # 注意此處使用 jdbc-url 而非 url:cite[1]
username: user_jtemplate
password: pass_jtemplate
driver-class-name: com.mysql.cj.jdbc.Driver
核心檢查點
-
Bean名稱與限定:檢查是否為每個
DataSource、JdbcTemplate、SqlSessionFactoryBean等定義了清晰的Bean名稱,并在注入時使用@Qualifier。 -
@Primary注解:通常將MyBatis使用的數據源設為@Primary,因為許多Spring Boot自動配置默認期望存在一個主數據源。 -
配置隔離:在
application.yml中使用不同的前綴(如spring.datasource.mybatis和spring.datasource.jdbctemplate)清晰隔離兩個數據源的配置。 -
URL屬性:在多數據源配置中,使用
jdbc-url而非url來避免潛在的配置解析問題

浙公網安備 33010602011771號