返回
Springboot Dynamic 多数据源集成攻略,轻松搞定数据库切换
后端
2022-11-02 05:22:56
Springboot Dynamic 多数据源集成教程:轻松切换数据库
在 Springboot 应用中,多数据源连接是常见需求。Dynamic 数据源机制提供了灵活的解决方案,让开发者轻松实现数据库切换,满足不同业务需求。
一、SpringBoot集成Dynamic实现多数据源
1. 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2. 配置数据源
在 application.yml
中定义多个数据源:
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: root
password: 123456
secondary:
url: jdbc:mysql://localhost:3306/secondary_db
username: root
password: 123456
3. 排除DataSourceAutoConfiguration类
Springboot 自动配置功能会自动创建默认数据源。要使用 Dynamic 数据源,需要排除自动配置类:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
4. 使用@DS实现数据源切换
通过 @DS
注解指定数据源:
@DS("primary")
public class PrimaryMapper {
// 省略 Mapper 方法
}
@DS("secondary")
public class SecondaryMapper {
// 省略 Mapper 方法
}
@Service
public class UserService {
@DS("primary")
public void primaryMethod() {
// 省略业务逻辑
}
@DS("secondary")
public void secondaryMethod() {
// 省略业务逻辑
}
}
二、常见问题及解决方案
1. 无法注入多个数据源
排除 pom.xml 中的 jdbc 或 mybatis jar 包。
2. 使用 @DS 注解后出现错误
确保 pom.xml 中引入了 Springboot 的依赖。
3. 数据库切换不生效
检查 @DS 注解是否正确使用,以及是否在 Service 或 Mapper 类上使用了正确的注解。
4. 事务问题
默认情况下,Dynamic 数据源不启用事务支持。如果需要事务,需要配置:
@Configuration
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
5. RoutingDataSource
通过自定义 RoutingDataSource 实现更灵活的数据源路由:
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 根据业务逻辑返回数据源 key
}
}
结论
Springboot Dynamic 数据源提供了灵活的机制,可实现数据库切换,满足多数据源访问需求。通过以上步骤,可以轻松集成 Dynamic 数据源,并解决常见问题。
附录:代码示例
配置 Dynamic 数据源
@Configuration
public class DataSourceConfig {
@Bean
public RoutingDataSource routingDataSource() {
RoutingDataSource routingDataSource = new RoutingDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("primary", primaryDataSource());
targetDataSources.put("secondary", secondaryDataSource());
routingDataSource.setTargetDataSources(targetDataSources);
routingDataSource.setDefaultTargetDataSource(primaryDataSource());
return routingDataSource;
}
@Bean
@Qualifier("primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/primary_db")
.username("root")
.password("123456")
.build();
}
@Bean
@Qualifier("secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/secondary_db")
.username("root")
.password("123456")
.build();
}
}
使用 RoutingDataSource
@Service
public class UserService {
@Autowired
private RoutingDataSource routingDataSource;
public void primaryMethod() {
routingDataSource.setCurrentLookupKey("primary");
// 业务逻辑
routingDataSource.clearLookupKey();
}
public void secondaryMethod() {
routingDataSource.setCurrentLookupKey("secondary");
// 业务逻辑
routingDataSource.clearLookupKey();
}
}