天天看點

commons-beanutils和反射解決查詢%和_資料問題注解+反射+commons-beanutils寫在最後

        我們的測試大神提出了問題單,輸入%和_會查詢到所有資料,需要修改。如果不修改,嚴重問題,版本轉測試不通過!!在我看來測試能提出這種問題真的是挺“業餘”的,那我就給他改一下。

        解決方式很簡單,無非就是在查詢前将可能帶有%和_的字段進行轉義。例如:

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攔截器去做,這樣會更友善,但是原理是一樣的!

寫在最後

最後希望我司的測試能多在架構、業務和性能優化上多發現問題和提出建議,不要當個體驗官,這樣在公司優化的時候你才能避免被淘汰。共勉!