Spring Boot 配置多数据源适用以下场景:
1. 分库分表:
- 当单个数据库无法满足系统容量要求,尤其是大数据量和高并发场景下,通常会采用分库分表策略,例如按用户ID哈希取模分布到不同的数据库实例上。
2. 读写分离:
- 为了提升系统的读性能,常采用主从数据库结构,主库负责写入操作,从库负责读取操作,减轻主库压力,提高查询速度。
3. 业务模块隔离:
- 复杂的系统可能由多个业务模块组成,各个模块间的数据不共享或者很少交互,此时可以为每个模块分配独立的数据源,达到数据隔离的目的。
4. 多租户系统:
- 在SaaS软件中,为了实现多租户模式,每个租户可能都有自己独立的数据库资源,因此需要在同一个应用中配置多个数据源以便根据不同租户切换数据库。
5. 历史数据归档:
- 对于需要长期保留的历史数据,可能会将其迁移至成本更低廉的存储或数据库,而实时数据则保留在高性能数据库中,这就涉及到了读取不同数据库的需求。
6. 跨系统数据同步:
- 如果系统需要对接多个外部系统,每个系统都有自己的数据库,那么就需要配置多个数据源来连接不同的数据库,进行数据的同步和交互。
Spring Boot 配置多数据源有多种方案,下面是一种通用且较为详细的方法:
1. 配置文件设置多个数据源
在 `application.yml` 或 `application.properties` 文件中配置多个数据源:
# application.yml 示例
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: user1
password: pass1
driver-class-name: com.mysql.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db
username: user2
password: pass2
driver-class-name: com.mysql.jdbc.Driver
2. 创建多个数据源配置类
对于每个数据源,编写一个配置类,继承`org.springframework.boot.autoconfigure.jdbc.DataSourceProperties`或者实现`javax.sql.DataSource`,并利用@Configuration和@Bean注解来声明和配置DataSource。
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
public class PrimaryDataSourceConfig {
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
}
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
public class SecondaryDataSourceConfig {
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
3. 配置多数据源的JdbcTemplate、EntityManagerFactory或JPA repositories
对于不同数据源,创建对应的数据源事务管理器和SQLSessionFactory(如果使用MyBatis)或EntityManagerFactory(如果使用JPA)。
@Configuration
public class PrimaryDatabaseConfig {
@Autowired
private DataSource primaryDataSource;
@Bean
public JdbcTemplate primaryJdbcTemplate() {
return new JdbcTemplate(primaryDataSource);
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
// ...配置主数据源的EntityManagerFactory
}
@Bean
@Primary
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(primaryEntityManagerFactory(builder).getObject());
}
}
// 对于第二个数据源做类似配置
@Configuration
public class SecondaryDatabaseConfig {
// ...
}
4. 使用多数据源
在业务代码中,通过`@Autowired`和`@Qualifier`注解来引用特定的数据源:
@Service
public class SomeService {
@Autowired
@Qualifier("primaryJdbcTemplate")
private JdbcTemplate primaryJdbcTemplate;
@Autowired
@Qualifier("secondaryJdbcTemplate")
private JdbcTemplate secondaryJdbcTemplate;
// 使用对应的数据源进行数据库操作
}
如果是使用MyBatis,可以在MyBatis的配置类中注入不同的SqlSessionFactory,并基于这些工厂创建Mapper。
5. 动态数据源路由(可选)
对于更复杂的应用场景,可能需要根据运行时条件动态选择数据源。这时可以实现一个`AbstractRoutingDataSource`子类,通过ThreadLocal或其他上下文存储机制保存当前线程的数据源标识,根据这个标识决定实际使用的数据源。
总结
配置Spring Boot多数据源的核心在于正确地配置多个数据源Bean,并在业务层面上明确区分使用哪个数据源进行操作。同时,要确保事务管理与数据源的绑定是正确的,以保证数据的一致性。