资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

spring中怎么通过注解切换多数据源

spring中怎么通过注解切换多数据源,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

开平网站制作公司哪家好,找成都创新互联公司!从网页设计、网站建设、微信开发、APP开发、响应式网站设计等网站项目制作,到程序开发,运营维护。成都创新互联公司于2013年创立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联公司

第一步,配置数据源


   
   
   
   
   
   
   
   
   

 

   
   
   
   
   
   
   
   
   

第二步,定义用来切库的注解,和枚举类

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Dataswitch {
    Datatype value() default Datatype.master;
}
public enum Datatype {
    master("masterDataSource"),slave("slaveDataSource");
    private String value;
    Datatype(String name){
        this.value = name;
    }
 
    public String getValue() {
        return value;
    }
 
    public void setValue(String value) {
        this.value = value;
    }
}

第三步,定义一个当前线程的变量的工具类,用于设置对应的数据源名称

public  class DynamicDataSourceHolder {
    private static final ThreadLocal threadLocal = new ThreadLocal();
 
    public static String getThreadLocal() {
        return threadLocal.get();
    }
 
    public static void setThreadLocal(String name) {
        threadLocal.set(name);
    }
    public static void clear(){
        threadLocal.remove();
    }
}

第四步,创建AbstactRoutingDataSource的子类,重写determineCurrentLockupKey方法

public class DynamicDataSource extends AbstractRoutingDataSource{
    protected Object determineCurrentLookupKey() {
        System.out.println(DynamicDataSourceHolder.getThreadLocal());
        return DynamicDataSourceHolder.getThreadLocal();
    }
}

第五步,将多数据源配置到用我们创建的DynamicDataSource


   
      
         
         
      
   
   

第六步,配置切面,在操作数据库方法之前,获取注解配置的数据源名称,返回

@Component
@Aspect
@Order(0)
public class DataSourceAspect {
    @Pointcut("execution (* xin.youhuila.sorceswitch.service..*(..))")
    public void aspect(){
 
    }
    @Before("aspect()")
    public void before(JoinPoint joinPoint){
        Class clazz = joinPoint.getTarget().getClass();
        Method[] method = clazz.getMethods();
        Dataswitch dataswitch = null;
        boolean is = false;
        for(Method m:method){//此处最好改成通过签名获取调用方法是否含有注解,而不是遍历每个方法,可参考http://www.gitout.cn/?p=2398
            if(m.isAnnotationPresent(Dataswitch.class)){
                dataswitch = m.getAnnotation(Dataswitch.class);
                DynamicDataSourceHolder.setThreadLocal(dataswitch.value().getValue());
                is = true;
            }
        }
        if(!is){
            DynamicDataSourceHolder.setThreadLocal(Datatype.master.getValue());
        }
    }
    @After("aspect()")
    public void after(){
        DynamicDataSourceHolder.clear();
    }
}

第七步,使用

@Service
public class DemoService {
    @Autowired
    DemoMapper demoMapper;
    @Dataswitch(Datatype.master)
    public void select(){
        List d = demoMapper.select();
        for(Demo demo:d){
            System.out.println(demo);
        }
    }
}

--------------------------------http://www.gitout.cn/?p=2398文章实现-----------------------

/**
 * 数据源切面
 */
@Aspect
@Component
public class DynamicDataSourceAspect {
	
	@Pointcut("@annotation(com...datasource.DynamicDataSourceAnnotation)") 
	public void pointCut() {
	}
	
	@Before("pointCut()")
	public void testBefore(JoinPoint point) {
		// 获得当前访问的class
		Class className = point.getTarget().getClass();
		DynamicDataSourceAnnotation dataSourceAnnotation = className.getAnnotation(DynamicDataSourceAnnotation.class);
		String dataSource = DataSourceConst.DB_ACTIVITY;
		// 优先级: 方法 > 类  > DB_ACTIVITY
		if(dataSourceAnnotation != null) {
			dataSource = dataSourceAnnotation.dataSource();
		}
		String methodName = point.getSignature().getName();
		// 得到方法的参数的类型
		Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();
		try {
			Method method = className.getMethod(methodName, argClass);
			if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) {
				DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class);
				dataSource = annotation.dataSource();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		DataSourceContextHolder.setDataSourceType(dataSource);

	}

	@After("pointCut()")
	public void testAfter(JoinPoint point) {
		// 获得当前访问的class
		Class className = point.getTarget().getClass();
		DynamicDataSourceAnnotation dataSourceAnnotation = className.getAnnotation(DynamicDataSourceAnnotation.class);
		if (dataSourceAnnotation != null) {
			// 获得访问的方法名
			String methodName = point.getSignature().getName();
			// 得到方法的参数的类型
			Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();
			String dataSource = DataSourceConst.DB_ACTIVITY;
			try {
				Method method = className.getMethod(methodName, argClass);
				if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) {
					DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class);
					dataSource = annotation.dataSource();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (dataSource != null && !DataSourceConst.DB_ACTIVITY.equals(dataSource)) {
				DataSourceContextHolder.clearDataSourceType();
			}
		}
	}
}

关于spring中怎么通过注解切换多数据源问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。


文章名称:spring中怎么通过注解切换多数据源
文章分享:http://cdkjz.cn/article/ihssic.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220