zoukankan      html  css  js  c++  java
  • mysql分库,动态数据库切换

    分库分表:解决思路,Dao-->ORM--->JDBC-->Proxy-->Server
    1分库
    在Dao层进行选择数据库
     package org.springframework.jdbc.datasource.lookup下的
    AbstractRoutingDataSource实现多数据源切换
    
    Dao层数据源切换:
    
    package com.example.demo.multdatasource;
    
    
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    
    /**
     * 多数据源切面
     */
    @Aspect
    @Slf4j
    @Component
    public class DataSourceAspect {
    
        @Pointcut("@annotation( com.example.demo.multdatasource.TargetDataSource)")
        public void pointcut() {
    
        }
        @Around("pointcut()")
        public Object Around(ProceedingJoinPoint proceedingJoinPoint) {
            MethodSignature methodSignature = (MethodSignature)proceedingJoinPoint.getSignature();
            Method method = methodSignature.getMethod();
            TargetDataSource annotation = method.getAnnotation(TargetDataSource.class);
            if(annotation==null){
                //目标方法上没有注解,设置默认为第一个数据源
                MyAbstractDataSource.setDtaSource(DataSourceNames.FIRST);
            }else{
                //目标方法伤有数据源,就设置数据源为注解里的数据源
                MyAbstractDataSource.setDtaSource(annotation.name());
            }
            try {
                return  proceedingJoinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }finally {
                MyAbstractDataSource.clearDataSource();
            }
            return null;
        }
    }
    
    package com.example.demo.multdatasource;
    
    /**
     * 多数据源选择设置处,也可以设置枚举
     */
    public interface DataSourceNames {
           String  FIRST = "FIRST";
           String   SECOND = "SECOND";
    }
    
    package com.example.demo.multdatasource;
    
    /**
     * 演示Dao层注解获取
     */
    public class MultDatraSourceDao {
        @TargetDataSource(name = DataSourceNames.SECOND)
        public Object getObject(){
            return  null;
        }
    }
    
    package com.example.demo.multdatasource;
    
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    import javax.sql.DataSource;
    import java.util.Map;
    
    /**
     * 多数据源切换实现
     */
    public class MyAbstractDataSource extends AbstractRoutingDataSource {
    
        private  static  final ThreadLocal<String> CONTEXT_HOLDER=new ThreadLocal<>();
    
        /**
         * 需要使用哪个数据源的信息以及默认数据源先配置好
         * @param defaultTargetDataSource
         * @param targetDataSources
         */
        public MyAbstractDataSource(DataSource defaultTargetDataSource, Map<Object,Object> targetDataSources) {
            super.setDefaultTargetDataSource(defaultTargetDataSource);
            super.setTargetDataSources(targetDataSources);
            super.afterPropertiesSet();
        }
    
        @Override
        protected Object determineCurrentLookupKey() {
            return getDataSource();
        }
        public static String getDataSource(){
            return CONTEXT_HOLDER.get();
        }
    
        public static void  setDtaSource(String dataSource){
            CONTEXT_HOLDER.set(dataSource);
        }
        public static  void clearDataSource(){
            CONTEXT_HOLDER.remove();
        }
    }
    
    package com.example.demo.multdatasource;
    
    import java.lang.annotation.*;
    
    /**
     * 数据源注解处
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    public @interface TargetDataSource {
        String name() default "";
    }
    
    package com.example.demo.multdatasource;
    
    
    import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;
    
    
    /**
     * 多数据源配置处
     */
    @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 MyAbstractDataSource dataSource(DataSource firstDataSource,DataSource secondDataSource){
          Map<Object,Object> targetDataSource=new HashMap<>();
            targetDataSource.put(DataSourceNames.FIRST,firstDataSource);
            targetDataSource.put(DataSourceNames.SECOND,secondDataSource);
            return new MyAbstractDataSource(firstDataSource,targetDataSource);
        }
    }
    
    一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰
  • 相关阅读:
    前端开发试题
    操作手册
    border-box有什么用
    npm安装react-dom...
    html-webpack-plugin按需加载的js/css也会被提取出来吗
    洛谷P3957 跳房子(Noip2017普及组 T4)
    【react】利用prop-types第三方库对组件的props中的变量进行类型检测
    React 进入页面以后自动 focus 到某个输入框
    React 更新阶段的生命周期 componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate
    React 生命周期 constructor->componentWillMount->render->componentDidMount->componentWillUnmount
  • 原文地址:https://www.cnblogs.com/wangbiaohistory/p/15084574.html
Copyright © 2011-2022 走看看