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); } }
一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰