• spring 多数据源切换


    spring配置管理多数据源,方便服务访问不同数据库时,数据源切换。多少无意,直接上代码。

    1.定义数据源key枚举值(可以直接使用字符串代替,为了代码的整洁及易读性,这里使用枚举)

    public enum DataSourceEnum {
    	anquan,
    	publ,
    	tlshow,
    }
    

    2.定义数据源持有者,切换数据源使用

    public final class DataSourceHolder {
    	private static ThreadLocal<DataSourceEnum> currentDBName = new ThreadLocal<DataSourceEnum>();
    	
    	private static DataSourceEnum DEFAULT_HASH = DataSourceEnum.anquan;
    
    	public static DataSourceEnum determineDefault() {
    		return determineDS(DEFAULT_HASH);
    	}
    
    	public static DataSourceEnum determineDS(DataSourceEnum key) {
    		currentDBName.set(key);
    		log.debug("determineDS:" + key);
    		return key;
    	}
    	
    	
    	public static DataSourceEnum getCurrentDBName() {
    		return currentDBName.get();
    	}
    }
    

    3.实现数据源路由接口

    public class DBRoutingDataSource extends AbstractRoutingDataSource {
    
    	@Override
    	protected Object determineCurrentLookupKey() {
    		return DataSourceHolder.getCurrentDBName();
    	}
    
    	@Override
    	public void setTargetDataSources(Map targetDataSources) {
    		super.setTargetDataSources(targetDataSources);
    	}
    	
    	@Override
    	public Object unwrap(Class iface) throws SQLException {
    		return null;
    	}
    
    	@Override
    	public boolean isWrapperFor(Class iface) throws SQLException {
    		return false;
    	}
    }
    

    4.定义spring 切面,在执行service方法前,切换数据源。(首先要保证spring支持注解)

    @Aspect
    @lombok.extern.log4j.Log4j
    public class DetermineAspect {
    	@Pointcut("within(com.changyou.*.service.impl.*)")
    	public void withController() {}
    
    	@Before("withController()")
    	public void beforeAdvice(JoinPoint jp) {
    		if(log.isDebugEnabled()) {
    			log.debug("Reset db router before " + jp.getSignature().getDeclaringType().getSimpleName() + "." + jp.getSignature().getName() + "()");
    		}
    		DataSourceMethod datasourceMethod = ((MethodSignature)jp.getSignature()).getMethod().getAnnotation(DataSourceMethod.class);
    		DataSourceFile datasourceFile = ((MethodSignature)jp.getSignature()).getMethod().getDeclaringClass().getAnnotation(DataSourceFile.class);
    		
    		if(datasourceMethod!=null){
    			DataSourceHolder.determineDS(datasourceMethod.value());
    		}else if(datasourceFile!=null){
    			DataSourceHolder.determineDS(datasourceFile.value());
    		}else{
    			DataSourceHolder.determineDefault();
    		}
    	}
    
    }
    

    5.spring配置数据源,使用自己实现的数据源路由类(DBRoutingDataSource 

    <!-- 配置数据源 -->
    	<bean name="dataSource_0" parent="abstractProxoolDataSource">
    		<property name="url" value="${jdbc.0.url}" />
    		<property name="username" value="${jdbc.0.username}" />
    		<property name="password" value="${jdbc.0.password}" />
    	</bean>
    	
    	<!-- 配置数据源tlshow-->
    	<bean name="dataSource_1" parent="abstractProxoolDataSource">
    		<property name="url" value="${jdbc.1.url}" />
    		<property name="username" value="${jdbc.1.username}" />
    		<property name="password" value="${jdbc.1.password}" />
    	</bean>
    	
    	<!-- 配置数据源publicaccount-->
    	<bean name="dataSource_2" parent="abstractProxoolDataSource">
    		<property name="url" value="${jdbc.2.url}" />
    		<property name="username" value="${jdbc.2.username}" />
    		<property name="password" value="${jdbc.2.password}" />
    	</bean>
    	
    	
    	<bean id="dataSource" class="com.changyou.common.util.dbaccess.DBRoutingDataSource">
    		<property name="defaultTargetDataSource" ref="dataSource_0"/>
    		<property name="targetDataSources">
    			<map key-type="com.changyou.common.enums.DataSourceEnum"><!-- 数据源枚举 -->
    				<entry key="anquan" value-ref="dataSource_0" />
    				<entry key="tlshow" value-ref="dataSource_1" />
    				<entry key="publ" value-ref="dataSource_2" />
    			</map>
    		</property>
    	</bean>
    

    6.基础工作完成,下面开始使用,需要在server类或方法上添加注解。(上面的切面会查看是否有指定注解的存在)。

      定义自己的注解:

    @Target(value={ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface DataSourceRouter {
    	public DataSourceEnum value() default DataSourceEnum.anquan;
    }
    

    7.开始愉快的使用吧,方法上的注解权限高于整个类上的注解,这取决于切面的处理方式。

    @Service
    @DataSourceRouter(DataSourceEnum.publ)
    public class CyjUserServiceImpl{
    
    	@Autowired
    	private UserMapper userMapper;
    	
    	public void saveOrUpdateBlock(CyjUserBlock cyjUserBlock) {
    		userMapper.saveOrUpdateBlock(cyjUserBlock);
    	}
    
            @DataSourceRouter(DataSourceEnum.anquan)
    	public void deleteBlockById(int blockId) {
    		userMapper.deleteBlockById(blockId);
    	}
    }
    

      

    ok,后期补上demo。。。。。。。

  • 相关阅读:
    VINTF
    Excel 公式
    SSIS ODBC方式连接mysql数据库
    SSIS错误汇总
    linux防火墙(转)
    如何查询域名的MX、A、DNS、txt、cname记录
    IP反向解析
    Visual Studio 内存泄漏检测方法
    strcpy慎用
    main函数前后执行代码
  • 原文地址:https://www.cnblogs.com/rmsSpring/p/5405403.html
Copyright © 2020-2023  润新知