1、编写多数据源的DataSource继承自AbstractRoutingDataSource
package com.mochenli.shardingshere.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author: MoChenLi
* @description:
* @createTime: 2024-06-27 23:09
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 数据源的名称对象
*/
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
/**
* 多数据源对现象
*/
private final Map<Object, Object> dynamicTargetDataSources = new ConcurrentHashMap<>();
/**
*
* 确定当前线程应该使用的数据源
* 核心方法
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return getDataSourceType();
}
/**
* 用于添加目标数据源
* @param key
* @param dataSource
*/
public void addDataSource(String key, DataSource dataSource) {
this.dynamicTargetDataSources.put(key, dataSource);
this.setTargetDataSources(dynamicTargetDataSources);
// 在添加数据源后,需要调用afterPropertiesSet()方法来更新内部的resolvedDataSources
this.afterPropertiesSet();
}
/**
* 根据数据源的key进行数据源的移除
* @param key
*/
public void removeDataSource(String key) {
this.dynamicTargetDataSources.remove(key);
this.setTargetDataSources(dynamicTargetDataSources);
// 在移除数据源后,需要调用afterPropertiesSet()方法来更新内部的resolvedDataSources
this.afterPropertiesSet();
}
/**
* 设置切换的数据源
* @param dataSourceType
*/
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}
/**
* 获取切换的数据源
* @return
*/
public static String getDataSourceType() {
return contextHolder.get();
}
/**
* 清除数据源
*/
public static void clearDataSourceType() {
contextHolder.remove();
}
}
2、编写数据源配置类
package com.mochenli.shardingshere.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
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.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
/**
* @author: MoChenLi
* @description:
* @createTime: 2024-06-27 21:23
*/
@Configuration
public class DataSourceConfig {
/**
*直接配置
* @return
*/
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/test?allowPublicKeyRetrieval=true");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
/**
* 根据配置文件构建数据源
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSource dataSourceOne(){
return DataSourceBuilder.create().build();
}
/**
* 主数据源
* @return
*/
@Bean
@Primary
public DataSource dynamicDataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.addDataSource("default",dataSource());
dynamicDataSource.addDataSource("default1",dataSourceOne());
dynamicDataSource.setDefaultTargetDataSource(dataSource());
return dynamicDataSource;
}
}
3、切换数据源使用
package com.mochenli.shardingshere.controller;
import com.mochenli.shardingshere.config.DynamicDataSource;
import com.mochenli.shardingshere.entity.Order;
import com.mochenli.shardingshere.mapper.OrderMapper;
import com.mochenli.shardingshere.service.ShardingConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author: MoChenLi
* @description:
* @createTime: 2024-06-18 16:35
*/
@RestController
public class UserController {
@Autowired
private OrderMapper orderMapper;
@Autowired
ShardingConfigService shardingConfigService;
@GetMapping("/test")
public Map<String,Object> test(){
Map<String,Object> map = new HashMap();
//使用数据源1
DynamicDataSource.setDataSourceType("default");
List<Map<String, Object>> maps = shardingConfigService.loadShardingConfig();
map.put("default",maps);
//使用数据源2
DynamicDataSource.setDataSourceType("default1");
List<Order> orders = orderMapper.selectAll();
map.put("default1",orders);
return map;
}
}
4、还可以使用dynamic-datasource
导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
用注解指定对应数据源
@DS(“数据源”)
但是dynamic-datasource的文档是加密的需要付费如果需要深入定制不友好