Spring提供一个DataSource实现类用于动态切换数据源——AbstractRoutingDataSource
pom.xml
<dependencies> <!--meiyouyemeishi--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.15</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter-test</artifactId> <version>3.0.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>
大概的项目结构
@RestController
public class TestController {
@Autowired
private StudentMapper studentMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private ApplicationContext context;
@RequestMapping("/test01")
//@Transactional
public Object test01(){
Student student=new Student();
student.setName("db1");
student.setAge("18");
student.setGender("男");
int i = studentMapper.insertStudent(student);
User user=new User(null,"db2", "123456");
int j = userMapper.insertUser(user);
return i+j;
}
@RequestMapping("/test02")
public Object test02(){
Student student=new Student();
student.setName("db1");
student.setAge("18");
student.setGender("男");
int i = studentMapper.insertStudent(student);
return i;
}
@RequestMapping("/test03")
public Object test03(){
User user=new User(null,"db2", "123456");
int i = userMapper.insertUser(user);
return i;
}
}
package com.example.demo3.datasource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @author hrui
* @date 2023/11/2 4:36
*/
@Component
@Aspect
@Order(-100)
public class DataSourceAop {
@Pointcut("execution(* com.example.demo3.mapper.*.*(..)) && @annotation(com.example.demo3.datasource.DataSourceTypeAnno)")
public void dataSourcePointcut(){}
@Around("dataSourcePointcut()")
public Object doAround(ProceedingJoinPoint pjp){
MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
Method method = methodSignature.getMethod();
DataSourceTypeAnno typeAnno = method.getAnnotation(DataSourceTypeAnno.class);
String value = typeAnno.value();
switch (value){
case "db1":DataSourceUtil.setDB("db1");break;
case "db2":DataSourceUtil.setDB("db2");break;
}
Object result = null ;
try {
result = pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}finally {
DataSourceUtil.setDB("db1");
}
return result;
}
}
注意:这两个事务管理器,并不能处理分布式事务文章来源:https://www.toymoban.com/news/detail-738449.html
@Configuration
public class DataSourceConfig {
/**
* 数据源1
* spring.datasource.db1:application.properteis中对应属性的前缀
* @return
*/
@Bean(name = "db1")
@ConfigurationProperties(prefix = "spring.datasource.db1")
public DataSource dataSourceOne() {
//return DataSourceBuilder.create().build();
return DruidDataSourceBuilder.create().build();
}//如果选druid连接池
/**
* 数据源2
* spring.datasource.db2:application.properteis中对应属性的前缀
* @return
*/
@Bean(name = "db2")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dataSourceTwo() {
//return DataSourceBuilder.create().build();
return DruidDataSourceBuilder.create().build();
}
/**
* 动态数据源: 通过AOP在不同数据源之间动态切换
* @return
*/
@Bean(name = "dynamicDataSource")
@Primary
public DataSource dynamicDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 默认数据源
dynamicDataSource.setDefaultTargetDataSource(db1);
// 配置多数据源
Map<Object, Object> dsMap = new HashMap<>();
dsMap.put("db1", db1);
dsMap.put("db2", db2);
//所有数据源
dynamicDataSource.setTargetDataSources(dsMap);
return dynamicDataSource;
}
// /**
// * 配置@Transactional注解
// * @return
// */
// @Bean
// public PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) { 这个有问题
// return new DataSourceTransactionManager(dynamicDataSource);
// }
@Bean
@Primary
public PlatformTransactionManager transactionManager1(@Qualifier("db1") DataSource dynamicDataSource) {
return new DataSourceTransactionManager(dynamicDataSource);
}
@Bean
public PlatformTransactionManager transactionManager2(@Qualifier("db2") DataSource dynamicDataSource) {
return new DataSourceTransactionManager(dynamicDataSource);
}
}
//控制注解的生命周期,什么时候起作用
@Retention(RetentionPolicy.RUNTIME)
//注解的作用对象: 类上 方法上 变量上
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
public @interface DataSourceTypeAnno {
String value() default "db1";
}
public class DataSourceUtil {
private static final ThreadLocal<String> local = new ThreadLocal();
/**
* 设置数据源名
* @param dbType
*/
public static void setDB(String dbType) {
local.set(dbType);
}
/**
* 获取数据源名
* @return
*/
public static String getDB() {
return local.get();
}
/**
* 清除数据源名
*/
public static void clearDB() {
local.remove();
}
}
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
log.info("动态获取数据源——{}",DataSourceUtil.getDB());
return DataSourceUtil.getDB();
}
}
链接:https://pan.baidu.com/s/1ymxeKYkI-cx7b5nTQX0KWQ
提取码:6bii
--来自百度网盘超级会员V4的分享 文章来源地址https://www.toymoban.com/news/detail-738449.html
到了这里,关于SpringBoot动态切换数据源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!