Spring Boot多數據源配置詳解
在實際企業開發中,隨著業務復雜度提升,單一數據源已無法滿足所有場景需求。比如:讀寫分離、分庫分表、數據遷移、微服務整合等,這時就需要用到多數據源配置。本文將從原理、配置、常見問題和最佳實踐等方面,帶你全面掌握Spring Boot多數據源的實現方式。
一、為什么要用多數據源?
- 讀寫分離:主庫寫、從庫讀,提升性能與可用性。
- 多業務數據庫:不同業務模塊獨立數據庫,降低耦合。
- 數據遷移/整合:新舊系統并行,數據同步。
- 多租戶/分庫分表:按租戶或業務分庫,提升擴展性。
二、Spring Boot多數據源實現原理
Spring Boot默認只配置一個DataSource
,多數據源本質上是注冊多個DataSource
Bean,并通過@Primary
、@Qualifier
等注解區分。每個數據源對應自己的JdbcTemplate
、TransactionManager
、MyBatis
或JPA
配置。
三、實戰:Spring Boot多數據源配置
1. 添加依賴
以MySQL和MyBatis為例:
<!-- pom.xml -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version>
</dependency>
2. 配置多數據源
# application.yml
spring:datasource:primary:url: jdbc:mysql://localhost:3306/db1username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driversecondary:url: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
3. 編寫數據源配置類
@Configuration
@MapperScan(basePackages = "com.example.mapper.db1", sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryDataSourceConfig {@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "primarySqlSessionFactory")public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);return bean.getObject();}@Bean(name = "primaryTransactionManager")public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean(name = "primarySqlSessionTemplate")public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}
}
@Configuration
@MapperScan(basePackages = "com.example.mapper.db2", sqlSessionTemplateRef = "secondarySqlSessionTemplate")
public class SecondaryDataSourceConfig {@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "secondarySqlSessionFactory")public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);return bean.getObject();}@Bean(name = "secondaryTransactionManager")public DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean(name = "secondarySqlSessionTemplate")public SqlSessionTemplate secondarySqlSessionTemplate(@Qualifier("secondarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}
}
4. 使用多數據源
只需將不同的Mapper接口分別放在com.example.mapper.db1
和com.example.mapper.db2
包下,Spring Boot會自動注入對應的數據源。
四、常見問題與解決方案
-
事務管理混亂
每個數據源要有獨立的TransactionManager
,并用@Transactional(transactionManager = "xxxTransactionManager")
指定。 -
Mapper掃描沖突
@MapperScan
要指定basePackages
和sqlSessionTemplateRef
,避免掃描到錯誤的數據源。 -
JPA多數據源
JPA配置類似,但需額外配置EntityManagerFactory
和PlatformTransactionManager
。
五、最佳實踐
- 命名規范:Bean、包名、配置前綴要清晰區分。
- 配置解耦:推薦用
@ConfigurationProperties
集中管理數據源配置。 - 動態數據源:如需動態切換,可用
AbstractRoutingDataSource
或開源組件(如druid、dynamic-datasource)。 - 安全性:敏感信息建議用加密或環境變量管理。
六、總結
Spring Boot多數據源配置并不復雜,關鍵在于理解原理、規范配置、合理分包。掌握多數據源技術,不僅能提升系統擴展性和靈活性,也是后端開發進階的必備技能。
如果你覺得本文有幫助,歡迎點贊、關注、轉發!如有疑問,歡迎留言交流。
如需Word版或代碼示例工程,請留言獲取!