在开发Web应用过程中,我们经常需要与不同的数据库交互,有时候甚至需要同时访问多个数据源。Spring Boot提供了强大的支持来简化多数据源的配置和管理,本文将介绍在Spring Boot应用中实现多数据源配置与切换的最佳实践。
添加依赖
首先,在pom.xml
文件中添加Spring Boot对于多数据源的支持依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
配置数据源
在application.properties
文件中配置多个数据源的相关信息:
# 数据源1
spring.datasource.url=jdbc:mysql://localhost:3306/database1
spring.datasource.username=your-username
spring.datasource.password=your-password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源2
datasource2.url=jdbc:mysql://localhost:3306/database2
datasource2.username=your-username
datasource2.password=your-password
datasource2.driver-class-name=com.mysql.cj.jdbc.Driver
配置数据源的配置类
创建一个DataSourceConfig
类,用于配置数据源:
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "dataSource1")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "datasource2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
}
创建数据源的JdbcTemplate
在每个数据源上创建一个对应的JdbcTemplate
,用于执行SQL语句:
@Configuration
public class JdbcTemplateConfig {
@Bean(name = "jdbcTemplate1")
public JdbcTemplate jdbcTemplate1(@Qualifier("dataSource1") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "jdbcTemplate2")
public JdbcTemplate jdbcTemplate2(@Qualifier("dataSource2") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
创建数据源的事务管理器
为每个数据源创建对应的事务管理器,实现事务的管理:
@Configuration
public class TransactionManagerConfig {
@Bean(name = "transactionManager1")
public PlatformTransactionManager transactionManager1(@Qualifier("dataSource1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "transactionManager2")
public PlatformTransactionManager transactionManager2(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
创建数据源的Repository
在每个数据源上创建对应的Repository接口,用于对数据库进行操作:
@Repository
public interface UserRepository1 extends JpaRepository<User, Long> {
// ...
}
@Repository
public interface UserRepository2 extends JpaRepository<User, Long> {
// ...
}
动态切换数据源
为了实现动态切换数据源,可以通过自定义注解和AOP的方式来实现。首先,创建一个自定义注解@DataSource
,用于标识具体的方法使用哪个数据源:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value() default "dataSource1";
}
然后,创建一个AOP切面类DataSourceAspect
,在该切面类中根据@DataSource
注解的值来切换数据源:
@Aspect
@Configuration
public class DataSourceAspect {
@Before("@annotation(dataSource)")
public void switchDataSource(JoinPoint point, DataSource dataSource) {
String dataSourceName = dataSource.value();
if (StringUtils.isNotBlank(dataSourceName)) {
DynamicDataSourceContextHolder.setDataSourceType(dataSourceName);
}
}
@After("@annotation(dataSource)")
public void restoreDataSource(JoinPoint point, DataSource dataSource) {
DynamicDataSourceContextHolder.clearDataSourceType();
}
}
配置AOP切面
最后,将DataSourceAspect
配置成一个AOP切面,实现数据源的动态切换:
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
@Autowired
private DataSource dataSource1;
@Autowired
private DataSource dataSource2;
@Bean
public DataSourceAspect dataSourceAspect() {
return new DataSourceAspect();
}
@Bean
public DynamicDataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setDefaultTargetDataSource(dataSource1);
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("dataSource1", dataSource1);
targetDataSources.put("dataSource2", dataSource2);
dynamicDataSource.setTargetDataSources(targetDataSources);
return dynamicDataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
测试数据源切换
最后,我们可以在业务代码中使用@DataSource
注解来指定具体的数据源:
@Service
public class UserService {
@Autowired
private UserRepository1 userRepository1;
@Autowired
private UserRepository2 userRepository2;
@DataSource("dataSource1")
public List<User> getAllUsersFromDataSource1() {
return userRepository1.findAll();
}
@DataSource("dataSource2")
public List<User> getAllUsersFromDataSource2() {
return userRepository2.findAll();
}
}
以上就是在Spring Boot应用中实现多数据源配置与切换的最佳实践。通过使用Spring Boot的相关组件,我们可以轻松地实现多个数据源的配置和切换,提高应用的灵活性和可扩展性。
本文来自极简博客,作者:软件测试视界,转载请注明原文链接:Spring Boot应用中实现多数据源配置与切换的最佳实践