栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot+MyBatis利用切面的方式配置多数据源

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot+MyBatis利用切面的方式配置多数据源

SpringBoot+MyBatis利用切面的方式配置多数据源

SpringBoot+MyBatis利用切面的方式配置多数据源,同时用druid监控sql

重点

1、AOP相关的知识,这里主要是切点的定位
2、重写AbstractRoutingDataSource的determineCurrentLookupKey方法
3、数据源的切换

项目结构

在分包的基础上增加切面相关的配置
![在这里插入图片描述](https://img-blog.csdnimg.cn/8dd45e82294749f1abaa528042ea5ab7.png

项目依赖
 		
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.0
        

        
        
            mysql
            mysql-connector-java
            8.0.16
            runtime
        

        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
           com.alibaba
           druid-spring-boot-starter
           1.1.10
       
       
       
           com.alibaba
           druid
           1.1.10
       

配置文件
spring.datasource.db1.url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.db1.username=root
spring.datasource.db1.password=123456
spring.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.db1.filters=stat
spring.datasource.db1.testOnBorrow=false
spring.datasource.db1.testOnReturn=false
spring.datasource.db1.testWhileIdle=true
spring.datasource.db1.validationQuery=SELECt 1
spring.datasource.druid.db1.inital-size=3
spring.datasource.druid.db1.min-idle=3
spring.datasource.druid.db1.max-active=10
spring.datasource.druid.db1.max-wait=60000
spring.datasource.druid.db1.filters.slf4j.enabled=true

spring.datasource.db2.url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.db2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.db2.username=root
spring.datasource.db2.password=123456
spring.datasource.db2.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.db2.filters=stat
spring.datasource.db2.testOnBorrow=false
spring.datasource.db2.testOnReturn=false
spring.datasource.db2.testWhileIdle=true
spring.datasource.db2.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.db2.inital-size=3
spring.datasource.druid.db2.min-idle=3
spring.datasource.druid.db2.max-active=10
spring.datasource.druid.db2.max-wait=60000
spring.datasource.druid.db2.filters.slf4j.enabled=true

mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
数据源配置

1、MultipleDatasourceConfig

@Configuration
public class MultipleDatasourceConfig {
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource db1() {
        return DataSourceBuilder.create().type(DruidDataSource.class).build();
    }

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

    @Primary
    @Bean("dynamicDatasource")
    public DataSource dynamicDatasource() {
        DynamicDatasource dynamicDatasource = new DynamicDatasource();
        // 配置默认数据源
        dynamicDatasource.setDefaultTargetDataSource(db1());

        // 配置多数据源
        Map datasourceMap = new HashMap<>();
        datasourceMap.put("db2", db2());
        dynamicDatasource.setTargetDataSources(datasourceMap);

        return dynamicDatasource;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDatasource());
    }
}

2、db1

@Configuration
@MapperScan(basePackages = "路径",sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class DB1DSConfig {
     static final String MAPPER_LOCATION = "classpath:mapper/mysql
@Configuration
@MapperScan(basePackages = "路径",sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class DB2DSConfig {
     static final String MAPPER_LOCATION = "classpath:mapper/mysql
public class DatasourceContextHolder {
    private static final Logger logger = LoggerFactory.getLogger(DatasourceContextHolder.class);

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

    public static void setDatasource(String name) {
        logger.info("切换到[{}]数据源", name);
        contextHolder.set(name);
        
    }

    public static String getDatasource() {
        return contextHolder.get();
    }

    public static void clearDatasource() {
        contextHolder.remove();
    }
}
切换数据源

AbstractRoutingDataSource类是Spring为方便的在项目中实现动态切换数据源而提供的一个抽象类, 我们只需要实现上面的这个抽象方法 即可 , 该方法用于返回当前需要切换的数据源的key;

public class DynamicDatasource extends AbstractRoutingDataSource {
    private static final Logger logger = LoggerFactory.getLogger(DynamicDatasource.class);

//    public DynamicDatasource(Datasource datasource, Map objectMap){
//        this.setDefaultTargetDataSource(datasource);
//        this.setTargetDataSources(objectMap);
//        this.afterPropertiesSet();
//    }

    @Override
    protected Object determineCurrentLookupKey() {
        String datasource = DatasourceContextHolder.getDatasource();
        if (datasource == null) {
            logger.info("当前数据源为[db1]");
            datasource = "db1";
        } else {
            logger.info("当前数据源为[{}]", datasource);
        }

        return datasource;
    }
}
切面拦截切换数据源
@Component
@Aspect
@Order(-1)// 使该切面调用优先于AbstractRoutingDataSource的determineCurrentLookupKey()
public class DynamicDatasourceAspect {
    @Pointcut("@annotation(数据源对象的路径,即Datasource的路径)")
    public void pointCut() {
        System.out.println("使用[@Pointcut]定义切入点");
    }

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        try {
            // 获取当前访问的class
            Class aClass = joinPoint.getTarget().getClass();

            // 获取当前访问的method
            String methodName = joinPoint.getSignature().getName();

            // 获取方法的参数类型数组
            Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();

            // 获取方法对象
            Method method = aClass.getDeclaredMethod(methodName, parameterTypes);

            Datasource datasource = method.getAnnotation(Datasource.class);
            if (null!=datasource){
                DatasourceContextHolder.setDatasource(datasource.value());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DatasourceContextHolder.clearDatasource();
        }
    }

    @After("pointCut()")
    public void after() {
        System.out.println("after");

        DatasourceContextHolder.clearDatasource();
    }
}

切点的路径即,上文动态的数据源对象的路径,也可以定义在service层,但是我这边只有定义在数据源对象这里才能实现切换

dao层配置指定数据源

1、db1

@Datasource(value = "db1")

2、db2

@Datasource(value = "db2")
暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1016367.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号