spring+mybatis plus实现多数据源


基本架构

SpringBoot+MybatisPlus实现多数据源,借助Spring-AOP实现数据源的动态切换.

整体流程

  • 定义注解,使用该注解配置具体方法使用的数据源,用于指明方法使用的数据源github

  • 定义通知advice:实现接口MethodBeforeAdvice, AfterReturningAdvice,用于在方法的执行前后切换数据源

  • 定义切面:这里通过实现接口PointcutAdvisor定义切面,其中定义切点覆盖所有需要拦截的方法(需要操作数据库的方法),引入具体的通知,即上一步定义的advice,并通过注解@Component将其注入到spring容器中

  • 定义封装数据源的工具类,使用ThreadLocal存储,通过字符串区分所使用的数据源

    public class DataSourceHolder {
        
        private static final ThreadLocal<String> DATA_SOURCES = new ThreadLocal<>();
        
        public static void setDataSources(String customerType) {
            DATA_SOURCES.set(customerType);
        }
        
        public static String getDataSource() {
            return DATA_SOURCES.get();
        }
        
        public static void clearDataSource() {
            DATA_SOURCES.remove();
        }
        
    }
    
  • 配置数据源的bean,并自定义动态数据源类实现接口AbstractRoutingDataSource,重写determineCurrentLookupKey方法返回多数据源具体的key

    public class DynamicDataSource extends AbstractRoutingDataSource {
        
        @Override
        protected Object determineCurrentLookupKey() {
            return DataSourceHolder.getDataSource();
        }
    }
    
  • 配置SqlSessionFactory的bean,设置其数据源为自定义的动态数据源(设置默认数据源以及多数据源Map)

        @Bean
        public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
            MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
            // 配置数据源,此处配置为关键配置,如果没有将 dynamicDataSource作为数据源则不能实现切换
            sqlSessionFactory.setDataSource(dynamicDataSource());
            // 扫描Model
            sqlSessionFactory.setTypeAliasesPackage("com.zdk.**.entity");
            return sqlSessionFactory.getObject();
        }
    
        @Bean
        public DynamicDataSource dynamicDataSource() {
            DynamicDataSource dataSource = new DynamicDataSource();
            Map<Object, Object> targetDataSource = new HashMap<>(16);
            targetDataSource.put("hello-world", helloWorldDataSource());
            targetDataSource.put("zdk-data", zdkDataDataSource());
            dataSource.setTargetDataSources(targetDataSource);
            dataSource.setDefaultTargetDataSource(helloWorldDataSource());
            return dataSource;
        }
    

注意

  • 切点的定义问题,注意切点的正则表达式能否覆盖到所有涉及到数据库操作的方法
  • MybatisPlus中使用MybatisSqlSessionFactoryBean作为SqlSessionFactory而非SqlSessionFactoryBean


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM