springboot配置双数据源 - haha_66666的博客 - CSDN博客

当一个项目中需要调用两个数据库时,这个时候就需要配置双数据源。

先配置配置文件

然后再Application类上加入:

@SpringBootApplication(

    exclude = {
            DataSourceAutoConfiguration.class
    }

)这个注解去除掉默认的数据库配置,然后我们自己去配置database.

DataSourceConfig类:

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.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
* @Author: ch
* @Date: 2018/6/27 11:06
* @Description:
*/
@Configuration
public class DataSourceConfig {

@Bean(name = "db")
@ConfigurationProperties(prefix = "spring.datasource.db")
public DataSource dataSource1() {
    return DataSourceBuilder.create().build();
}

@Bean(name = "db2")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dataSource2() {
    return DataSourceBuilder.create().build();
}

/\*\*
 \* 动态数据源: 通过AOP在不同数据源之间动态切换
 \*
 \* @return
 */
@Primary
@Bean(name = "dynamicDS1")
public DataSource dataSource() {
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    // 默认数据源
    dynamicDataSource.setDefaultTargetDataSource(dataSource1());

    // 配置多数据源
    Map<Object, Object> dsMap = new HashMap(5);
    dsMap.put("db", dataSource1());
    dsMap.put("db2", dataSource2());

    dynamicDataSource.setTargetDataSources(dsMap);
    return dynamicDataSource;
}
/\*\*
 \* 配置@Transactional注解事物
 \* @return
 */
@Bean
public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource());
}

}

DynamicDataSource 类

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
* @Author: ch
* @Date: 2018/6/27 11:40
* @Description:
*/
public class DynamicDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
    return DataSourceContextHolder.getDB();
}

}

DynamicDataSourceAspect 类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
* @Author: ch
* @Date: 2018/6/27 11:48
* @Description:
*/
@Aspect
@Component
public class DynamicDataSourceAspect {

@Before("@annotation(DS)")
public void beforeSwitchDS(JoinPoint point){

    //获得当前访问的class
    Class<?> className = point.getTarget().getClass();

    //获得访问的方法名
    String methodName = point.getSignature().getName();
    //得到方法的参数的类型
    Class\[\] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
    String dataSource = DataSourceContextHolder.DEFAULT_DS;
    try {
        // 得到访问的方法对象
        Method method = className.getMethod(methodName, argClass);

        // 判断是否存在@DS注解
        if (method.isAnnotationPresent(DS.class)) {
            DS annotation = method.getAnnotation(DS.class);
            // 取出注解中的数据源名
            dataSource = annotation.value();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    // 切换数据源
    DataSourceContextHolder.setDB(dataSource);

}


@After("@annotation(DS)")
public void afterSwitchDS(JoinPoint point){
    DataSourceContextHolder.clearDB();

}

}

DataSourceContextHolder 类

public class DataSourceContextHolder {

/\*\*
 \* 默认数据源
 */
public static final String DEFAULT_DS = "db";

private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

// 设置数据源名
public static void setDB(String dbType) {
    contextHolder.set(dbType);
}

// 获取数据源名
public static String getDB() {
    return (contextHolder.get());
}

// 清除数据源名
public static void clearDB() {
    contextHolder.remove();
}

}

DS 类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @Author: ch
* @Date: 2018/6/27 11:47
* @Description:
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({

    ElementType.METHOD

})
public @interface DS {

String value() default "db";

}

默认的数据库在调用的时候不用加任何的东西,按照正常的方式去使用即可,而使用到第二个数据库的serviceImpl的方法上加上

@DS("db2")即可,这样这个方法中的mapper文件就会调用不是默认的那个数据库了。


Original url: Access
Created at: 2019-10-14 16:02:02
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论