springboot2版本项目中已经整合了mybatis框架,yml文件中配置好了数据源, 现在想再使用jdbcTemplate查询另外一个数据库,需要怎么配置
# 这是你现有的MyBatis数据源配置(假设使用默认前缀)
spring:datasource:url: jdbc:mysql://localhost:3306/main_dbusername: rootpassword: passworddriver-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: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver# 可以根据需要配置连接池参数,例如HikariCP:hikari:maximum-pool-size: 10minimum-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"的Beanprivate JdbcTemplate secondaryJdbcTemplate;public List<Map<String, Object>> queryFromOtherDatabase() {String sql = "SELECT * FROM some_table";// 使用secondaryJdbcTemplate执行查询,操作的就是另一个数据库return secondaryJdbcTemplate.queryForList(sql);} }
重要的注意事项
-
事务管理:需要特别注意事务问题。如果你在使用了
@Transactional
注解的方法中操作多个数据源,默认的事务管理器可能只管理其中一个数据源的事务。你需要为每个数据源配置独立的PlatformTransactionManager
Bean,并在@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>