十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
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 ThreadLocalthreadLocal = 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(){ Listd = 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中怎么通过注解切换多数据源问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。