1、yml数据源配置
spring:
mvc:
throw-exception-if-no-handler-found: true
static-path-pattern: /static/**
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
save:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/save?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
2、自定义注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited //可以继承
public @interface DB {
String value();
}
3、切换数据源类
public class DynamicDataSource extends AbstractRoutingDataSource {
public static final String DEFAULTDB = "master";
public static ThreadLocal<String> contextHolder = new ThreadLocal<>();
//这个可写可不写,甚至可以忽略
public static ThreadLocal<String> getContextholder() {
return contextHolder;
}
/**
* 切换数据源
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
/**
* 设置数据源
* @param dataSorce
*/
public static void setDataSorce(String dataSorce){
contextHolder.set(dataSorce);
}
/**
* 获取数据源
* @return
*/
public static String getDataSource(){
return contextHolder.get();
}
/**
* 清除数据源
*/
public static void clearDataSource(){
contextHolder.remove();
}
}
4、数据源配置类
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource dataSourceMaster(){
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.save")
public DataSource dataSourceSave(){
return DataSourceBuilder.create().build();
}
@Primary
@Bean
public DataSource dynamicDataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
//设置默认的数据源
dynamicDataSource.setDefaultTargetDataSource(dataSourceMaster());
//添加数据源
Map<Object,Object> dBMap = new HashMap<>();
dBMap.put("master",dataSourceMaster());
dBMap.put("save",dataSourceSave());
dynamicDataSource.setTargetDataSources(dBMap);
return dynamicDataSource;
}
/**
* 添加事务
* @return
*/
@Bean
public PlatformTransactionManager platformTransactionManager(){
return new DataSourceTransactionManager(dynamicDataSource());
}
}
5、Aop切面动态切换数据源
5.1:注意:这里判断的是方法上注解,目前判断类上的注解就会报错,找不到表,后面研究下类上的注解,然后再做修改,报错如下:
@Order(-1)
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(com.alibaba.config.datasourceconf.DB)")
public void ponincut(){}
@SuppressWarnings("rawtypes")
// @Before("@annotation(com.alibaba.config.datasourceconf.DB) || @within(com.alibaba.config.datasourceconf.DB)")
@Before("ponincut()")
public void beforeAspect(JoinPoint joinPoint){
//获取当前访问的类名
Class<?> className = joinPoint.getTarget().getClass();
System.out.println("当前类:"+className);
//获取当前访问方法名
String methodName = joinPoint.getSignature().getName();
System.out.println("当前方法名:"+methodName);
//获取当前访问的参数类型
Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
for (Class parameterType : parameterTypes) {
System.out.println("参数类型:"+parameterType);
}
//获取当前访问的参数名字
String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
for (String parameterName : parameterNames) {
System.out.println("参数名字:"+parameterName);
}
//获取当前的参数值
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
System.out.println("参数值:"+arg);
}
//获取当前的数据源
String defaultdb = DynamicDataSource.DEFAULTDB;
try {
//获取当前方法的对象
Method method = className.getMethod(methodName, parameterTypes);
System.out.println("当前的对象1:"+method);
DB classAnnotion = className.getAnnotation(DB.class);
System.out.println(classAnnotion);
//判断是否有DB该注解
if (method.isAnnotationPresent(DB.class)){
//获取当前方法的DB注解
DB annotation = method.getAnnotation(DB.class);
System.out.println("当前方法的注解:"+annotation);
//获取当前注解的值
defaultdb = annotation.value();
System.out.println("当前注解的值:"+defaultdb);
}
} catch (Exception e) {
e.printStackTrace();
}
//切换数据源
DynamicDataSource.setDataSorce(defaultdb);
}
/**
* 清除数据源
*/
@After("ponincut()")
public void afterAspect(){
DynamicDataSource.clearDataSource();
}
}
6、实现类
@Service
public class DymincDataServiceImpl implements DymincDataService {
@Autowired
private DymincDataMapper dymincDataMapper;
// 这里查询的是save数据源
@Override
@DB(value = "save")
public PageInfo<CheckItem> findCheck(Integer currentPage, Integer pageSize) {
PageHelper.startPage(currentPage,pageSize);
List<CheckItem> check = dymincDataMapper.findCheck();
PageInfo<CheckItem> checkItemPageInfo = new PageInfo<>(check);
return checkItemPageInfo;
}
//这里没有注解就是默认的数据源
@Override
public PageInfo<Test> findTest(Integer currentPage, Integer pageSize) {
PageHelper.startPage(currentPage,pageSize);
List<Test> test = dymincDataMapper.findTest();
PageInfo<Test> testPageInfo = new PageInfo<>(test);
return testPageInfo;
}
}