| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Simple Spring Boot Multi-DataSource
// In Mapper
@UsingDataSource(DataSourceType.SLAVE)
User selectByPrimaryKey(Integer id);
// Or In Service
@UsingDataSource(DataSourceType.MASTER)
public User getUserFromSlave1(Integer id) {
return userDao.selectByPrimaryKey(id);
}
@UsingDataSource(DataSourceType.SLAVE)
public User getUserFromSlave(Integer id) {
return userDao.selectByPrimaryKey(id);
}在 application.yml 中添加数据源对应的配置信息
spring:
datasource:
master:
jdbc-url: jdbc:mysql://localhost:3306/multi_datasource_master
username: root
password: rootroot
slave:
jdbc-url: jdbc:mysql://localhost:3306/multi_datasource_slave
username: root
password: rootroot
slave2:
jdbc-url: jdbc:mysql://localhost:3306/multi_datasource_slave_2
username: root
password: rootroot数据源配置
@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class DataSourceConfig {
/**
* 主库数据源配置,Bean name 与 {@link DataSourceType} 中对应枚举类型名相同,以达到校验作用
*/
@Bean("MASTER")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 从库 1 数据源配置
*/
@Bean("SLAVE")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 从库 2 数据源配置
*/
@Bean("SLAVE_2")
@ConfigurationProperties(prefix = "spring.datasource.slave2")
public DataSource slave2DataSource() {
return DataSourceBuilder.create().build();
}
}定义数据源类型枚举
public enum DataSourceType {
/**
* 主库
*/
MASTER,
/**
* 从库 1
*/
SLAVE,
/**
* 从库 2
*/
SLAVE_2,
;
/**
* 默认的数据源类型
*/
public static final DataSourceType DEFAULT = MASTER;
}动态数据源配置,配合 UsingDataSource、UsingDataSourceAspect 实现数据源切换
@Primary
@Component
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
private final Map<String, DataSource> dataSourceMap;
public static final ThreadLocal<DataSourceType> TYPE_HOLDER = ThreadLocal.withInitial(() -> DataSourceType.DEFAULT);
public DynamicRoutingDataSource(Map<String, DataSource> dataSourceMap) {
this.dataSourceMap = dataSourceMap;
}
@Override
protected Object determineCurrentLookupKey() {
return TYPE_HOLDER.get();
}
@PostConstruct
private void postConstruct() {
// 设置默认数据源
String defaultDataSourceName = DataSourceType.DEFAULT.name();
DataSource defaultDataSource = dataSourceMap.get(defaultDataSourceName);
setDefaultTargetDataSource(defaultDataSource);
// 设置数据源及其类型映射
Map<Object, Object> targetDataSources = new HashMap<>();
dataSourceMap.forEach((name, ds) -> targetDataSources.put(DataSourceType.valueOf(name), ds));
setTargetDataSources(targetDataSources);
}
}指定使用数据源类型注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UsingDataSource {
DataSourceType value() default DataSourceType.MASTER;
}数据源切换拦截切面
@Slf4j
@Aspect
@Component
public class UsingDataSourceAspect {
@Around("@annotation(usingDataSource)")
public Object around(ProceedingJoinPoint joinPoint, UsingDataSource usingDataSource) throws Throwable {
DataSourceType type = usingDataSource.value();
log.debug("data source type is {}", type);
// 保存要切换到的数据源类型
DynamicRoutingDataSource.TYPE_HOLDER.set(type);
Object res;
try {
res = joinPoint.proceed();
} finally {
// 恢复数据源
DynamicRoutingDataSource.TYPE_HOLDER.remove();
}
return res;
}
}使用
@Service
public class UserService {
private final UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public User getUser(Integer id) {
return userDao.selectByPrimaryKey(id);
}
@UsingDataSource
public User getUserFromDefault(Integer id) {
return userDao.selectByPrimaryKey(id);
}
@UsingDataSource(DataSourceType.SLAVE)
public User getUserFromSlave1(Integer id) {
return userDao.selectByPrimaryKey(id);
}
@UsingDataSource(DataSourceType.SLAVE_2)
public User getUserFromSlave2(Integer id) {
return userDao.selectByPrimaryKey(id);
}
}Have fun! 😁
你可以使用 MultiDatasourceApplicationTests.getUser() 进行测试
@SpringBootTest
class MultiDatasourceApplicationTests {
@Autowired
private UserService userService;
@Test
void contextLoads() {
}
@Test
public void getUser() {
User user;
user = userService.getUser(1);
System.out.println("user = " + user);
user = userService.getUserFromDefault(1);
System.out.println("user = " + user);
user = userService.getUserFromSlave1(1);
System.out.println("user = " + user);
user = userService.getUserFromSlave2(1);
System.out.println("user = " + user);
user = userService.getUser(1);
System.out.println("user = " + user);
user = userService.getUserFromDefault(1);
System.out.println("user = " + user);
user = userService.getUserFromSlave1(1);
System.out.println("user = " + user);
user = userService.getUserFromSlave2(1);
System.out.println("user = " + user);
}
}user = User(id=1, username=master_username, password=master_password, sex=1, create_time=Fri Feb 19 11:59:35 CST 2021, update_time=Fri Feb 19 11:59:35 CST 2021, deleted=0)
2021-02-20 10:02:12.169 INFO 13053 --- [ main] c.e.m.config.UsingDataSourceAspect : data source type is MASTER
user = User(id=1, username=master_username, password=master_password, sex=1, create_time=Fri Feb 19 11:59:35 CST 2021, update_time=Fri Feb 19 11:59:35 CST 2021, deleted=0)
2021-02-20 10:02:12.171 INFO 13053 --- [ main] c.e.m.config.UsingDataSourceAspect : data source type is SLAVE
user = User(id=1, username=slave_username, password=slave_password, sex=1, create_time=Fri Feb 19 17:05:37 CST 2021, update_time=Fri Feb 19 17:05:37 CST 2021, deleted=0)
2021-02-20 10:02:12.186 INFO 13053 --- [ main] c.e.m.config.UsingDataSourceAspect : data source type is SLAVE_2
user = User(id=1, username=slave_2_username, password=slave_2_password, sex=1, create_time=Sat Feb 20 10:00:59 CST 2021, update_time=Sat Feb 20 10:00:59 CST 2021, deleted=0)
user = User(id=1, username=master_username, password=master_password, sex=1, create_time=Fri Feb 19 11:59:35 CST 2021, update_time=Fri Feb 19 11:59:35 CST 2021, deleted=0)
2021-02-20 10:02:12.203 INFO 13053 --- [ main] c.e.m.config.UsingDataSourceAspect : data source type is MASTER
user = User(id=1, username=master_username, password=master_password, sex=1, create_time=Fri Feb 19 11:59:35 CST 2021, update_time=Fri Feb 19 11:59:35 CST 2021, deleted=0)
2021-02-20 10:02:12.206 INFO 13053 --- [ main] c.e.m.config.UsingDataSourceAspect : data source type is SLAVE
user = User(id=1, username=slave_username, password=slave_password, sex=1, create_time=Fri Feb 19 17:05:37 CST 2021, update_time=Fri Feb 19 17:05:37 CST 2021, deleted=0)
2021-02-20 10:02:12.208 INFO 13053 --- [ main] c.e.m.config.UsingDataSourceAspect : data source type is SLAVE_2
user = User(id=1, username=slave_2_username, password=slave_2_password, sex=1, create_time=Sat Feb 20 10:00:59 CST 2021, update_time=Sat Feb 20 10:00:59 CST 2021, deleted=0)| Back | FazBrowse Home | New Git URL |