很长一段时间没有发技术贴,一方面感觉没什么可以好分享的,另一方面这一段时间主要从事服务端开发工作,发觉以前写的代码是个渣渣。。。
做过接口测试的童鞋应该都了解,假设你们的系统中有支付系统、用户管理系统、商品系统等等,各个系统分别有自己的数据库,这个时候接口校验数据库的时候,需要从多个数据库读取数据,有可能采用的是土方法,分别连接不同数据库去读取数据,我现在分享的也是土方法,不过做了层封装,长的漂亮点而已;PS: 抖音看多了,化妆跟不化妆是神区别
这边简单说下原理,
1.在 spring-jdbc.xml 中设置多个数据数据库的连接信息,然后使用 spring 的 AbstractRoutingDataSource 指定对应的数据库,并使用 defaultTargetDataSource 设置默认数据库
2.这个时候根据写好的自定义注解,在对应的 Mapper 方法,例如查找方法上增加注解,指定要查找某个数据库
3.AOP 切面的方法要在对应的 spring-server.xml 中进行初始化,否则 aop 切面不能正常生效
4.完了,就可以随便找个案例进行测试了
package com.finger.test.common;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* Created by 飞狐 on 2018/6/26.
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
System.out.println("DynamicDataSource数据源选择:" + DynamicDataSourceHolder.getDataSource());
return DynamicDataSourceHolder.getDataSource();
}
}
package com.finger.test.common;
/**
* Created by huqingen on 2018/6/26.
*/
public class DynamicDataSourceHolder {
public static final ThreadLocal<String> hodler = new ThreadLocal<String>();
public static void putDataSource(String name){
hodler.set(name);
}
public static String getDataSource(){
return hodler.get();
}
public static void clearHolder(){
hodler.set(DataSourceConst.LANYA);
}
}
package com.finger.test.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by huqingen on 2018/6/26.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataSource {
String value() default DataSourceConst.LANYA;
}
package com.finger.test.common.net;
import com.finger.test.common.DataSource;
import com.finger.test.common.DataSourceConst;
import com.finger.test.common.DynamicDataSourceHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
/**
* Created by huqingen on 2018/6/26.
*/
public class DataSourceAspect {
private Log LOG = LogFactory.getLog(DataSourceAspect.class);
public Object around(ProceedingJoinPoint point){
try {
Object annotation = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(DataSource.class);
if(annotation == null || !(annotation instanceof DataSource)){
DynamicDataSourceHolder.putDataSource(DataSourceConst.LANYA);
LOG.info("现在选择的是:" + DataSourceConst.LANYA );
} else {
DynamicDataSourceHolder.putDataSource(((DataSource) annotation).value());
LOG.info("现在选择的是:" + ((DataSource) annotation).value() );
}
} catch (Exception e){
LOG.error("获取数据源失败",e);
}
try {
Object result = point.proceed();
DynamicDataSourceHolder.clearHolder();
return result;
}catch (Throwable e){
throw new RuntimeException(e);
}
}
}
/**
* Created by 飞狐 on 2018/6/26.
*/
public class DataSourceTest extends BaseSupport{
@Autowired
private UserInfoDOMapper userInfoDOMapper;
@Autowired
private LYUserInfoDoMapper lyUserInfoDoMapper;
@Test
public void test1(){
//获取蓝芽用户信息
System.out.println(lyUserInfoDoMapper.selectByPrimaryKey(7300L).getRealName());
//获取Finger用户信息
System.out.println(userInfoDOMapper.selectByPrimaryKey(9996L).getUserNick());
}
}
写文章不是我擅长的点,比较喜欢直接代码面对面。。。
欢迎各位童鞋多多关注 我们公司产品 Finger,爱好音乐的都可以在上面玩起来