在Spring Boot中实现多数据源切换是一个常见需求,特别是在大型应用中,我们可能需要连接多个数据库来处理不同的数据。通过动态数据源的方式,我们可以根据不同的业务需求选择不同的数据源。下面我们通过示例来说明如何在Spring Boot中实现多数据源切换。
1. 项目依赖
首先,在pom.xml
中添加必要的依赖,主要是Spring Boot Starter和JdbcTemplate等相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
2. 配置文件
在application.yml
中配置多个数据源:
spring:
datasource:
first:
url: jdbc:h2:mem:firstdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
driver-class-name: org.h2.Driver
second:
url: jdbc:h2:mem:seconddb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
driver-class-name: org.h2.Driver
3. 数据源配置类
为了实现多数据源切换,我们需要创建数据源配置类。以下是一个示例:
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "firstDataSourceProperties")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Primary
@Bean(name = "firstDataSource")
public DataSource firstDataSource(@Qualifier("firstDataSourceProperties") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
@Bean(name = "secondDataSourceProperties")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "secondDataSource")
public DataSource secondDataSource(@Qualifier("secondDataSourceProperties") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
4. 动态数据源选择
为了在运行时选择使用哪个数据源,我们可以使用ThreadLocal
存储当前的数据源标识。
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String dataSourceType) {
contextHolder.set(dataSourceType);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
}
5. 使用示例
你可以在Service层中设置和清除数据源:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;
@Transactional
public void useFirstDataSource() {
DynamicDataSource.setDataSource("first");
// 访问第一个数据源的逻辑
}
@Transactional
public void useSecondDataSource() {
DynamicDataSource.setDataSource("second");
// 访问第二个数据源的逻辑
}
public void clearDataSource() {
DynamicDataSource.clearDataSource();
}
}
6. 总结
以上就是在Spring Boot中实现多数据源切换的基本方法。通过使用动态数据源,结合ThreadLocal
来存储当前的数据源信息,我们可以在不同的业务逻辑中灵活地选择所需的数据源,实现多数据源的动态切换。这在微服务架构或大规模应用中尤为重要,可以有效地提高系统的可用性和扩展性。