我們的測試大神提出了問題單,輸入%和_會查詢到所有資料,需要修改。如果不修改,嚴重問題,版本轉測試不通過!!在我看來測試能提出這種問題真的是挺“業餘”的,那我就給他改一下。
解決方式很簡單,無非就是在查詢前将可能帶有%和_的字段進行轉義。例如:
if (StringUtils.isNotBlank(logInfo.getAccount())) {
String account = logInfo.getAccount();
if (account.contains("%")) {
account = account.replaceAll("\\%","\\\\%");
}
if (account.contains("%")) {
account = account.replaceAll("\\%","\\\\%");
}
if (account.contains("_")) {
account = account.replaceAll("\\_","\\\\_");
}
logInfo.setAccount(account);
}
以上例子中,account為帶查詢的字段。
但是!如果每個方法都這樣查詢,難免太繁瑣了,而且容易遺忘!為了不讓我們的測試提問題單,我決定優化一下。
注解+反射+commons-beanutils
本篇采用java注解+反射機制和引入commons-beanutils包來解決。
定義注解@SpecChar
/**
* 特殊字元處理注解,主要用來解決測試大神提的%和_查詢問題
* 希望我司測試大神能滿意
* 希望我司測試大神增強自己的實力,不要隻會體驗
* 真正的測試比開發要牛
* 共勉!
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SpecChar {
}
當我們在定義實體類的時候,在需要查詢的字段上面加上這個注解!例如:
@Data
public class OrgManageSceneDto extends OrgManageScene{
@SpecChar
private String sceneName;
}
引入commons-beanutils包,記得引入1.9.3,否則會報錯哦
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
以上完事後,編寫統一方法,查詢的時候隻需要調用統一方法即可!
/**
* 處理特殊字元‘%’、‘_’
* @param object
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchMethodException
*/
public static Object setSpecChar(Object object) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
if (object == null) {
return object;
}
for (Field field : getAllFields(object)) {
if (field.getAnnotation(SpecChar.class) != null) {
String name = field.getName();
Object value = PropertyUtils.getSimpleProperty(object, name);
if (value != null) {
String valueStr = (String) value;
if (valueStr.contains("%")) {
valueStr = valueStr.replaceAll("\\%","\\\\%");
}
if (valueStr.contains("_")) {
valueStr = valueStr.replaceAll("\\_","\\\\_");
}
PropertyUtils.setProperty(object, name, valueStr);
}
}
}
return object;
}
/**
* 擷取類的所有屬性,包括父類
*
* @param object
* @return
*/
public static Field[] getAllFields(Object object) {
Class<?> clazz = object.getClass();
List<Field> fieldList = new ArrayList<>();
while (clazz != null) {
fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
clazz = clazz.getSuperclass();
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
}
在調用DAO層之前先調用此方法:
//調用一下
orgManageSceneDto = (OrgManageSceneDto) StructureUtil.setSpecChar(orgManageSceneDto);
List<OrgManageVo> list = orgManageMapper.getOrgManageScene(orgManageSceneDto);
以上解決問題,我們不用再每次都自己去轉義了。
當然我們既然定義了注解,還可以用切面和mybatis攔截器去做,這樣會更友善,但是原理是一樣的!
寫在最後
最後希望我司的測試能多在架構、業務和性能優化上多發現問題和提出建議,不要當個體驗官,這樣在公司優化的時候你才能避免被淘汰。共勉!