美文网首页
SpringBoot 配置动态数据源

SpringBoot 配置动态数据源

作者: 夏_0327 | 来源:发表于2018-11-07 17:44 被阅读0次

    数据源配置文件,数据库连接池使用Druid。

    spring:
        datasource:
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: oracle.jdbc.OracleDriver
            druid:
                first:  #数据源1
                    url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
                    username: root
                    password: root
                second:  #数据源2
                    url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
                    username: root
                    password: root
                initial-size: 10
                max-active: 100
                min-idle: 10
                max-wait: 60000
                pool-prepared-statements: true
                max-pool-prepared-statement-per-connection-size: 20
                time-between-eviction-runs-millis: 60000
                min-evictable-idle-time-millis: 300000
                validation-query: SELECT 1 FROM DUAL
                test-while-idle: true
                test-on-borrow: false
                test-on-return: false
                stat-view-servlet:
                    enabled: true
                    url-pattern: /druid/*
                    #login-username: admin
                    #login-password: admin
                filter:
                    stat:
                        log-slow-sql: true
                        slow-sql-millis: 1000
                        merge-sql: true
                    wall:
                        config:
                            multi-statement-allow: true
    
    /**
     * 配置多数据源
     * @author ysguo
     * @date 2018-03-21
     */
    @Configuration
    public class DynamicDataSourceConfig {
    
        @Bean
        @ConfigurationProperties("spring.datasource.druid.first")
        public DataSource firstDataSource(){
            return DruidDataSourceBuilder.create().build();
        }
    
        @Bean
        @ConfigurationProperties("spring.datasource.druid.second")
        public DataSource secondDataSource(){
            return DruidDataSourceBuilder.create().build();
        }
    
        @Bean
        @Primary
        public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
            Map<String, DataSource> targetDataSources = new HashMap<>();
            targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
            targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
            return new DynamicDataSource(firstDataSource, targetDataSources);
        }
    }
    
    /**
     * 动态数据源
     * @author ysguo
     * @date 2018-03-21
     */
    public class DynamicDataSource extends AbstractRoutingDataSource {
        private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    
        public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
            super.setDefaultTargetDataSource(defaultTargetDataSource);
            super.setTargetDataSources(new HashMap<>(targetDataSources));
            super.afterPropertiesSet();
        }
    
        @Override
        protected Object determineCurrentLookupKey() {
            return getDataSource();
        }
    
        public static void setDataSource(String dataSource) {
            contextHolder.set(dataSource);
        }
    
        public static String getDataSource() {
            return contextHolder.get();
        }
    
        public static void clearDataSource() {
            contextHolder.remove();
        }
    
    }
    
    /**
     * 增加多数据源,在此配置
     *
     * @author ysguo
     * @date 2018-03-21
     */
    public interface DataSourceNames {
        String FIRST = "first";
        String SECOND = "second";
    
    }
    
    /**
     * 多数据源注解
     * @author ysguo
     * @date 2018-03-21
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface DataSource {
        String name() default "";
    }
    
    /**
     * 多数据源,切面处理类
     * @author ysguo
     * 
     * @date 2018-03-21
     */
    @Aspect
    @Component
    public class DataSourceAspect implements Ordered {
        protected Logger logger = LoggerFactory.getLogger(getClass());
    
        @Pointcut("@annotation(com.ysguo.datasources.annotation.DataSource)")
        public void dataSourcePointCut() {
    
        }
    
        @Around("dataSourcePointCut()")
        public Object around(ProceedingJoinPoint point) throws Throwable {
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
    
            DataSource ds = method.getAnnotation(DataSource.class);
            if(ds == null){
                DynamicDataSource.setDataSource(DataSourceNames.FIRST);
                logger.debug("set datasource is " + DataSourceNames.FIRST);
            }else {
                DynamicDataSource.setDataSource(ds.name());
                logger.debug("set datasource is " + ds.name());
            }
    
            try {
                return point.proceed();
            } finally {
                DynamicDataSource.clearDataSource();
                logger.debug("clean datasource");
            }
        }
    
        @Override
        public int getOrder() {
            return 1;
        }
    }
    

    在Service方法上使用@DataSource注解切换数据源

    @Service
    public class UserInfoServiceImpl implements UserInfoService {
        @Autowired
        private UserInfoMapper userInfoMapper;
    
        @Override
        @DataSource(name=DataSourceNames.SECOND)
        public List<User> getUserInfoById(Integer userId) {
            return this.userInfoMapper.getUserInfoById(userId);
        }
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot 配置动态数据源

          本文链接:https://www.haomeiwen.com/subject/yyovxqtx.html