zoukankan      html  css  js  c++  java
  • springboot2.0.3:读写分离,使用AOP根据方法名动态切换数据源。

    springboot版本:2.0.3!!!

    springboot版本:2.0.3!!!

    springboot版本:2.0.3!!!

    我搭好的环境是:springboot 2.0.3+mybatis

    大致流程:
    方法执行前 -> 切换数据源 -> 执行sql

    • 取消单数据源默认配置
    @SpringBootApplication(exclude = {
    		DataSourceAutoConfiguration.class
    })
    public class PalletDemoApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(PalletDemoApplication.class, args);
    	}
    }
    
    @Aspect
    @Component
    @Lazy(false)
    @Order(0) //Order设定AOP执行顺序 使之在数据库事务上先执行
    public class SwitchDataSourceAOP {
        //这里切到你的方法目录
        @Before("execution(* com.zed.palletdemo.service.*.*(..))")
        public void process(JoinPoint joinPoint) {
            String methodName=joinPoint.getSignature().getName();
            if (methodName.startsWith("get")
                    ||methodName.startsWith("count")
                    ||methodName.startsWith("find")
                    ||methodName.startsWith("list")
                    ||methodName.startsWith("select")
                    ||methodName.startsWith("check")){
                DataSourceContextHolder.setDbType("selectDataSource");
            }else {
                //切换dataSource
                DataSourceContextHolder.setDbType("updateDataSource");
            }
        }
    }
    
    
    • 上面用到了一个类:DataSourceContextHolder看他怎么写的
    @Component
    @Lazy(false)
    public class DataSourceContextHolder {
        private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    
        public static void setDbType(String dbType) {
            contextHolder.set(dbType);
        }
    
        public static String getDbType() {
            return contextHolder.get();
        }
    
        public static void clearDbType() {
            contextHolder.remove();
        }
    
    }
    
    • 配置两个数据源bean,一会切换
    @Configuration
    public class DataSourceConfig {
    
        @Bean(name = "selectDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.select") // application.properteis中对应属性的前缀
        public DataSource dataSource1() {
            return DataSourceBuilder.create().build();
        }
        
        @Bean(name = "updateDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.update") // application.properteis中对应属性的前缀
        public DataSource dataSource2() {
            return DataSourceBuilder.create().build();
        }
    
    }
    
    • 切面主要切换数据源名称,这里正式生效
    @Component
    @Primary//不知道什么用,不加报错
    public class DynamicDataSource extends AbstractRoutingDataSource {
        @Autowired
        @Qualifier("selectDataSource")
        private DataSource selectDataSource;
    
        @Autowired
        @Qualifier("updateDataSource")
        private DataSource updateDataSource;
    
        /**
         * 这个是主要的方法,返回的是生效的数据源名称
         */
        @Override
        protected Object determineCurrentLookupKey() {
            System.out.println("DataSourceContextHolder:::"+DataSourceContextHolder.getDbType());
            return DataSourceContextHolder.getDbType();
        }
    
        /**
         * 自己配的时候老是报什么没有指定target这里设置一下,默认数据源是updateDataSource
         */
        @Override
        public void afterPropertiesSet() {
            Map<Object,Object> map = new HashMap<>();
            map.put("selectDataSource",selectDataSource);
            map.put("updateDataSource",updateDataSource);
            setTargetDataSources(map);
            setDefaultTargetDataSource(updateDataSource);
            super.afterPropertiesSet();
        }
    }
    
    • 然后service层方法注意一下命名,就可以动态切换了。
    • 我配的两个数据源
    spring:
      datasource:
        select:
          jdbc-url: jdbc:mysql://127.0.0.1:3306/test1
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: 123456
        update:
          jdbc-url: jdbc:mysql://127.0.0.1:3306/test2
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: 123456
        type: com.alibaba.druid.pool.DruidDataSource
    

    问题

  • 相关阅读:
    Matlab 绘制三维立体图(以地质异常体为例)
    Azure DevOps的variable group实现array和hashtable参数的传递
    Azure DevOps 利用rest api设置variable group
    Azure AADSTS7000215 其中一种问题的解决
    Power BI 实现实时更新Streaming Dataset
    AAD Service Principal获取azure user list (Microsoft Graph API)
    Matlab 沿三维任意方向切割CT图的仿真计算
    Azure Powershell script检测登陆并部署ARM Template
    Azure KeyVault设置策略和自动化添加secrets键值对
    Azure登陆的两种常见方式(user 和 service principal登陆)
  • 原文地址:https://www.cnblogs.com/myzoneliver/p/9309664.html
Copyright © 2011-2022 走看看