spring boot中通过dynamic datasource实现在启动中动态添加删除数据源的所有代码
时间: 2023-12-10 10:42:27 浏览: 221
dynamic-datasource-spring-boot-starter_多数据源_
5星 · 资源好评率100%
在Spring Boot中,使用Dynamic DataSource可以实现在启动中动态添加删除数据源。下面是一个简单的示例代码:
1. 添加Dynamic DataSource的依赖:
```
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.5</version>
</dependency>
```
2. 创建DataSourceConfig类,用于配置Dynamic DataSource:
```java
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public DataSource dynamicDataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
DataSource defaultDataSource = dataSource();
targetDataSources.put("default", defaultDataSource);
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(targetDataSources);
return dynamicDataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dynamicDataSource());
}
@PostConstruct
public void init() {
Map<String, Object> dataSourceProperties = new HashMap<>();
dataSourceProperties.put("driverClassName", driverClassName);
dataSourceProperties.put("url", url);
dataSourceProperties.put("username", username);
dataSourceProperties.put("password", password);
DataSource dataSource = DynamicDataSource.createDataSource(
"test", dataSourceProperties, HikariDataSource.class.getName());
DynamicDataSource.dynamicAddDataSource("test", dataSource);
}
}
```
在上面的代码中,我们通过@Bean注解创建了一个dataSource和dynamicDataSource。其中,dataSource是默认数据源,dynamicDataSource是Dynamic DataSource。
在@PostConstruct注解的init方法中,我们创建了一个名为test的新数据源,并将其添加到Dynamic DataSource中。
3. 创建DynamicDataSource类:
```java
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> dataSourceHolder = new ThreadLocal<>();
public static void dynamicAddDataSource(String key, DataSource dataSource) {
DynamicDataSource.dynamicDataSourceHolder.set(key);
DynamicDataSource.dynamicTargetDataSources.put(key, dataSource);
DynamicDataSource.dynamicDataSourceHolder.remove();
}
public static void dynamicRemoveDataSource(String key) {
DynamicDataSource.dynamicDataSourceHolder.set(key);
DynamicDataSource.dynamicTargetDataSources.remove(key);
DynamicDataSource.dynamicDataSourceHolder.remove();
}
private static final Map<Object, Object> dynamicTargetDataSources = new HashMap<>();
@Override
protected Object determineCurrentLookupKey() {
return dynamicDataSourceHolder.get();
}
@Override
protected Map<Object, Object> determineTargetDataSource() {
return dynamicTargetDataSources;
}
}
```
在上面的代码中,我们创建了一个DynamicDataSource类,继承了AbstractRoutingDataSource类,并实现了determineCurrentLookupKey和determineTargetDataSource方法。
我们通过ThreadLocal来保存当前线程所使用的数据源,而dynamicTargetDataSources则保存了所有的数据源。
通过dynamicAddDataSource方法,我们可以动态地向Dynamic DataSource中添加一个新的数据源。通过dynamicRemoveDataSource方法,我们可以动态地从Dynamic DataSource中删除一个数据源。
4. 在业务代码中使用Dynamic DataSource:
```java
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<User> getUsers() {
String sql = "SELECT * FROM user";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
}
public void addUser(User user) {
String sql = "INSERT INTO user (name, age) VALUES (?, ?)";
jdbcTemplate.update(sql, user.getName(), user.getAge());
}
}
```
在上面的代码中,我们使用了JdbcTemplate来查询和更新数据库。JdbcTemplate会自动地选择当前线程所使用的数据源。
通过上面的代码示例,我们可以在启动中动态添加和删除数据源,实现了更灵活的数据源管理。
阅读全文