赞
踩
本文主要介绍在QA人员测试过程中使用到ava多数据源切换,主要会涉及到springboot的自定义注解,动态数据源切面(AOP)、
提示:以下是本篇文章正文内容,下面案例可供参考
db.propertise设置数据库相关配置
#新系统数据库配置
new.mysql.host=192.168.xxx.xxx:3306
new.mysql.user=root
new.mysql.pass=xxxxx
读取propertise配置信息
import org.springframework.core.io.ClassPathResource; import java.io.*; import java.util.Properties; public class DBUtil { public static final String CONFIG_FILE_PATH="conf/db.properties"; //通过key直接获取对应的值 public static String getValue(String key) { Properties props=new Properties(); try { ClassPathResource resource=new ClassPathResource(CONFIG_FILE_PATH); InputStream in=resource.getInputStream(); BufferedReader bf=new BufferedReader(new InputStreamReader(in,"UTF-8")); props.load(bf); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } return props.getProperty(key); } }
多数据源配置DBConfig
import com.alibaba.druid.pool.DruidDataSource; import com.test.qa.util.DBUtil; import org.junit.Test; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @Configuration public class DBConfig { private static final String newDbHost = DBUtil.getValue("new.mysql.host"); private static final String newDbname = DBUtil.getValue("new.mysql.user"); private static final String newDbpass = DBUtil.getValue("new.mysql.pass"); public DruidDataSource userDb() throws SQLException { return DruidDataSourceFactory.getSimpleDruidDataSource("jdbc:mysql://"+newDbHost+"/finance_user?useSSL=false", newDbname, newDbpass); } public DruidDataSource loanDb() throws SQLException { return DruidDataSourceFactory.getSimpleDruidDataSource("jdbc:mysql://"+newDbHost+"/finance_loan?useSSL=false", newDbname, newDbpass); } @Bean(name = "dynamicDataSource") public DataSource dataSource() throws Exception { DynamicDataSource dynamicDataSource = new DynamicDataSource(); // 默认数据源 dynamicDataSource.setDefaultTargetDataSource(aggDb()); // 配置多数据源 Map<Object, Object> dsMap = new HashMap<>(); dsMap.put("aggDb", aggDb()); dsMap.put("userDb", userDb()); dynamicDataSource.setTargetDataSources(dsMap); return dynamicDataSource; } }
动态数据源DruidDataSourceFactory
import com.alibaba.druid.pool.DruidDataSource; import java.sql.SQLException; /** * 动态数据源 */ public class DruidDataSourceFactory { /** * 构建一个简单的数据源 * @param args * @return */ public static DruidDataSource getSimpleDruidDataSource(String ... args) throws SQLException{ DruidDataSource dataSource = new DruidDataSource(); if (args.length < 3){ throw new IllegalArgumentException("参数错误,请至少输入url,username,password三个配置!"); }else if (args.length == 3){ dataSource.setUrl(args[0]); dataSource.setUsername(args[1]); dataSource.setPassword(args[2]); }else { dataSource.setUrl(args[0]); dataSource.setUsername(args[1]); dataSource.setPassword(args[2]); dataSource.setMaxActive(Integer.parseInt(args[3])); } dataSource.setInitialSize(2); dataSource.setMinIdle(2); dataSource.setTimeBetweenEvictionRunsMillis(10000); dataSource.setMinEvictableIdleTimeMillis(60000); dataSource.setValidationQuery("SELECT 'x'"); dataSource.setTestWhileIdle(true); dataSource.setTestOnBorrow(false); dataSource.setTestOnReturn(false); dataSource.setRemoveAbandoned(true); dataSource.setRemoveAbandonedTimeout(1800); dataSource.setLogAbandoned(true); dataSource.setFilters("stat"); dataSource.setConnectionProperties("druid.stat.slowSqlMillis=100"); return dataSource; } }
动态数据源切换DruidDataSourceFactory
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源切换
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}
DataSourceContextHolder类
/** * 动态数据源 */ public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); /** * @param dataSourceType 数据库类型 * @Description: 设置数据源类型 */ public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } /** * @Description: 获取数据源类型 */ public static String getDataSourceType() { return contextHolder.get(); } /** * @Description: 清除数据源类型 */ public static void clearDataSourceType() { contextHolder.remove(); } }
动态数据源切面
/** * 动态数据源切面 */ @Aspect @Order(1) public class DynamicDataSourceAspect { /** * 切面选择需要切换的数据库 * @param joinPoint */ @Around("@annotation(com.test.qa.anotations.UseDataBase)") public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable{ Object target = joinPoint.getTarget(); Object[] args = joinPoint.getArgs(); Method method = getMethod(joinPoint, args); //获取数据库名称参数 UseDataBase chooseDataSource = method.getAnnotation(UseDataBase.class); if(chooseDataSource != null){ String dataSourceName = chooseDataSource.value(); DataSourceContextHolder.setDataSourceType(dataSourceName); //System.out.println("当前数据库为:"+dataSourceName); } try { return joinPoint.proceed(); }finally { DataSourceContextHolder.clearDataSourceType(); } } /** * 获取切面的方法 * @param joinPoint * @param args * @return * @throws NoSuchMethodException */ private Method getMethod(ProceedingJoinPoint joinPoint, Object[] args) throws NoSuchMethodException { String methodName = joinPoint.getSignature().getName(); Class clazz = joinPoint.getTarget().getClass(); Method[] methods = clazz.getMethods(); for(Method method : methods) { if (methodName.equals(method.getName())) { return method; } } return null; } }
通过自定义注解,方便数据源的切换
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 用于数据源的切换 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface UseDataBase { /** * 使用的数据库名称 * @return */ String value(); }
监听
/**
* 开启整个测试框架的监听
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Import({DynamicDataSourceAspect.class})
public @interface EnableTestingListener {
String value() default "";
}
/**
* springBoot启动器
*/
@SpringBootApplication
@EnableTestingListener
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
@Repository @Slf4j public class dbDao { @Autowired private JdbcTemplate jdbcTemplate; //通过UseDataBase注解切换数据源 @UseDataBase("loanDb") public Map<String,Object> find(String id){ String querySQL = "SELECT * FROM loan_bill WHERE id = '%s';"; querySQL = String.format(querySQL,id); log.info("执行SQL==>{}",querySQL); try { return jdbcTemplate.queryForMap(querySQL); }catch (Exception e){ log.error("执行SQL失败,信息为==>{}",e.toString()); return null; } } }
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class test1 {
@Autowired
private dbDao dbDao;
@Test
public void test(){
System.out.println(dbDao.find2("27").get("user_id"));
}
}
执行结果结果

这一块介绍完了,喜欢的可以点赞哦,谢谢
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。