二、配置动态数据源
前面我们已经准备了基础的类,@DynamicDatasource、DruidProperties、DynamicAspect
现在我们开始对 AbstractRoutingDatasource 所需要的数据源,放到对应的map结构中。
1、加载数据源
/**
* 功能描述 加载自定义的数据源,存入到 Map<String,Datasource> 结构中
*
* @author [山沉]
* @个人博客 [https://choleen95.github.io/]
* @博客 [https://www.cnblogs.com/Choleen/]
* @since [2023/6/4 10:00]
*/
@Component
@EnableConfigurationProperties(DruidProperties.class)
public class LoadDataSource {
@Autowired
DruidProperties druidProperties;
public Map<String, DataSource> loadDatasource() {
Map<String, DataSource> map = new HashMap<>();
// 获取自定义数据源的属性
Map<String, Map<String, String>> druidMap = druidProperties.getDruid();
try {
// 数据源名称 master、slave
Set<String> keySet = druidMap.keySet();
for (String name : keySet) {
map.put(name, druidProperties.dataSource(
((DruidDataSource) DruidDataSourceFactory.createDataSource(druidMap.get(name)))));
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
}
2、设置默认、目标数据源
/**
* 功能描述 重写AbstractRoutingDataSource 的一个方法
*
* @author [山沉]
* @个人博客 [https://choleen95.github.io/]
* @博客 [https://www.cnblogs.com/Choleen/]
* @since [2023/6/3 22:49]
*/
@Component
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
public DynamicRoutingDataSource(LoadDataSource loadDatasource) {
Map<String, DataSource> allDataSource = loadDatasource.loadDatasource();
// 1.设置所有数据源
super.setTargetDataSources(new HashMap<>(allDataSource));
// 2.设置默认的数据源
super.setDefaultTargetDataSource(allDataSource.get(DataSourceType.DEFAULT_DS_TYPE));
// 3.设置配置
super.afterPropertiesSet();
}
/**
* 该方法是用来返回数据源的名称,当系统需要获取数据源的时候,会自动调用该方法获取数据源的名称
*
* @author 山沉
* @date 2023/6/4 10:12
* @return {@link Object}
*/
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDatasourceType();
}
}
到了这一步基本就设置完成,总的来说就是依据 AbstracRoutingDataSource 来存储 target 和 default 的数据源,重写 determineCurrentLookupKey 方法。
/**
* 功能描述 常用配置变量
*
* @author [山沉]
* @个人博客 [https://choleen95.github.io/]
* @博客 [https://www.cnblogs.com/Choleen/]
* @since [2023/6/4 10:22]
*/
public interface DataSourceType {
String DEFAULT_DS_TYPE = "master";
}
3、单元测试
3.0 创建service、mapper、domian
@Service
public class LoginUserService {
@Autowired
private LoginUserMapper loginUserMapper;
public List<LoginUser> getAllLoginUsers() {
return loginUserMapper.getAllLoginUsers();
}
}
public class LoginUser {
private Long id;
private String name;
@Override
public String toString() {
return "LoginUser{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Mapper
public interface LoginUserMapper {
/**
* 查找所有的登录用户
*
* @author 山沉
* @date 2023/6/4 10:41
* @return {@link List< LoginUser>}
*/
@Select("select * from t_login_user")
List<LoginUser> getAllLoginUsers();
}
然后看下数据库
tesdb2、testdb 两个库中有相同的t_login_user表
slave对应如下
master对应如下
3.1 直接访问
直接访问,不添加注解,是默认数据源