`
一夕剑
  • 浏览: 55203 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

解决使用通配符%或_,进行查询时可以查出所有数据的问题

    博客分类:
  • Java
 
阅读更多

1.对与标题中提到的问题,相信很多有点经验的web端开发者,都会觉得这不是很简单的事情么。

第一种方法:将需要进行模糊查询的字段处理一下就可以了,例如字段中包含的%替换为\\%。

第二种方法:如果使用的是mysql,还可以使用escape定义转义字符,例如escape '/',将'/'定义为转义字符,再将字段包括的%,替换为/%,‘/’后面的%i不会被认为是通配符而是当作普通字符进行处理。

上面的两种方法,确实可以解决问题,但是需要在每个接口中,对与可以模糊查询的字段,遂个进行处理,如果有大量接口都有可以进行模糊查询的字段,有没有更简单的一点的办法呢,答案是肯定的。

1.对于post的请求,使用json进行数据传递,可以通过定义

1.1前端使用json进行传递数据,例如

{

"pageNum":1,

"pageSize":10,

"userName":"%"

}

1.2后端在control中,接收数据时使用@RequestBody注解接收类型参数

1.3在需要进行字符转义的模糊查询字段上,标注@JsonDeserialize(using = WildcardFieldDeserializer.class),WildcardFieldDeserializer为自定义的反序列化操作类

1.4 在WildcardFieldDeserializer中实现通配符的替换操作处理

/**
 * 对需要模糊查询的字段,进行通配符转义处理
 */
public class WildcardFieldDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException,
            JsonProcessingException {
        String resultStr = jsonParser.getText();
        if (null != jsonParser && StringUtils.isNotEmpty(resultStr)) {
            if (resultStr.contains("%") || resultStr.contains("_")) {
                resultStr = resultStr.replace("%", "\\%");
                resultStr = resultStr.replace("_", "\\_");
            }
            return resultStr;
        } else {
            return null;
        }
    }
}

 

2对于get的请求,可以通过在request数据映射绑定操作时,进行通配符的替换操作处理,具体操作步骤如下

2.1定义注解,用于标识需要进行通配符转义替换的字段

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldWildcard {
}

 2.2自定义进行数据绑定操作的类,此类需继承ExtendedServletRequestDataBinder

public class FieldWildcardDataBinder extends ExtendedServletRequestDataBinder {
    private final List<String> fieldWildcardList;

    public FieldWildcardDataBinder(Object target, String objectName, List<String> fieldWildcardList) {
        super(target, objectName);
        this.fieldWildcardList = fieldWildcardList;
    }

    @Override
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
        super.addBindValues(mpvs, request);
        String fieldValue = null;
        PropertyValue propertyValue;
        for (String field : fieldWildcardList) {
            propertyValue = mpvs.getPropertyValue(field);
            if (null != propertyValue && null != propertyValue.getValue()) {
                fieldValue = BaseUtil.handlerWildcard(propertyValue.getValue().toString());
            }
            mpvs.add(field, fieldValue);
        }
    }
}

 2.3 自定义一个模型属性方法处理器,继承自ServletModelAttributeMethodProcessor,主要用于收集需要进行通配符转义替换操作的字段

/**
 * 对request中的parameter,映射到javabean中的属性时,做相关的处理
 */
public class FieldWildcardProcessor extends ServletModelAttributeMethodProcessor {
    @Autowired
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

    /**
     * 将标有FieldWildcard注解的字段的属性名与处理过的属性值缓存起来
     */
    private final Map<Class<?>, List<String>> filedWildcardMap = new ConcurrentHashMap<>();

    /**
     * Class constructor.
     *
     * @param annotationNotRequired if "true", non-simple method arguments and
     *                              return values are considered model attributes with or without a
     *                              {@code @ModelAttribute} annotation
     */
    public FieldWildcardProcessor(boolean annotationNotRequired) {
        super(annotationNotRequired);
    }

    @Override
    protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
        Object target = binder.getTarget();
        List<String> fieldWildcardList = getFieldWildcardList(target.getClass());
        FieldWildcardDataBinder fieldWildcardDataBinder = new FieldWildcardDataBinder(target, binder.getObjectName(),
                fieldWildcardList);
        requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(fieldWildcardDataBinder, request);
        super.bindRequestParameters(fieldWildcardDataBinder, request);
    }

    private List<String> getFieldWildcardList(Class<?> targetClass) {
        if (targetClass == Object.class) {
            return Collections.emptyList();
        }
        if (filedWildcardMap.containsKey(targetClass)) {
            return filedWildcardMap.get(targetClass);
        }
        List<String> replaceValueList = new ArrayList<>();
        Field[] declaredFields = targetClass.getDeclaredFields();
        for (Field field : declaredFields) {
            FieldWildcard fieldAnnotation = field.getAnnotation(FieldWildcard.class);
            if (null != fieldAnnotation) {
                field.setAccessible(true);
                replaceValueList.add(field.getName());
            }
        }
        replaceValueList.addAll(getFieldWildcardList(targetClass.getSuperclass()));
        if (replaceValueList.isEmpty()) {
            return Collections.emptyList();
        }
        filedWildcardMap.put(targetClass, replaceValueList);
        return replaceValueList;
    }


}

 2.4自定义一个配置处理类,继承自WebMvcConfigurerAdapter,实现addArgumentResolvers方法,引入自定义的参数绑定方法处理类

@Configuration
public class WebDataConvertConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(fieldWildcardProcessor());
    }

    @Bean
    FieldWildcardProcessor fieldWildcardProcessor() {
        return new FieldWildcardProcessor(true);
    }

}

 

 当control中的方法,参数没有使用@RequestBody注解标示时,此方法也可用于post请求

get方法的处理逻辑,参考自https://www.jianshu.com/p/1d167eac801e

 

分享到:
评论

相关推荐

    C#使用%通配符进行查询

    在这个主题中,我们将深入探讨如何使用%通配符进行查询,这对于熟悉SQL语法和C#中的数据库操作至关重要。%通配符在SQL中被广泛用于模糊匹配,它允许我们在查询中寻找不完全匹配的数据。 首先,%通配符有以下两种...

    SQL中查询中使用通配符

    当你在查询中使用`%`时,数据库系统会返回所有与之匹配的数据,无论该位置有多少个字符。例如,如果你想查询名字中包含"Smith"的所有用户,可以使用以下语句: ```sql SELECT * FROM Users WHERE Name LIKE '%...

    Mysql| 使用通配符进行模糊查询详解(like,%,_)

    在MySQL数据库中,模糊查询是一种非常实用的查询方式,它允许我们使用通配符来匹配不完全确定的数据。本文将详细讲解如何使用`LIKE`操作符配合通配符`%`和`_`进行模糊查询。 `LIKE`操作符是MySQL中用于执行模糊匹配...

    浅谈MySQL模糊查询中通配符的转义

    sql中经常用like进行模糊查询,而模糊查询就要用到百分号“%”,下划线“_”这些通配符,其中“%”匹配任意多个字符,“_”匹配单个字符。如果我们想要模糊查询带有通配符的字符串,如“60%”,“user_name”,就...

    数据库作业6:SQL练习3 – SELECT(单表查询)

    匹配串:可以是一个完整的字符串,也可以含有通配符%和 _(模糊查询) % (百分号)代表任意长度(长度可以为0)的字符串 _ (下横线)代表任意单个字符 匹配串为固定字符串: [例3.29] 查询学号为201215121的学生的...

    C#通配符数据库查询实例

    在处理大量数据时,还可以考虑使用数据适配器(SqlDataAdapter)和数据集(DataSet),它们可以在内存中缓存查询结果,方便进一步处理。此外,对于异步操作,SqlCommand提供了BeginExecuteReader和EndExecuteReader...

    SQL语言中使用的通配符

    SQL语言中使用的通配符是数据库查询中非常重要的概念,它们可以帮助开发者更方便地查询和匹配数据库中的数据。在SQL Server中,通配符主要有四种: "_"、"%"、"[]"和"[^]",每种通配符都有其特定的使用场景和用法。 ...

    解决MySql大数据Like查询慢的问题

    3. **使用SOUNDEX或MATCH...AGAINST**:SOUNDEX是一种英文单词的音近字匹配函数,MATCH...AGAINST则是全文搜索的一部分,它们可以帮助优化模糊匹配,尤其是在处理自然语言数据时。 4. **前缀索引**:如果总是对某个...

    IKVM7.4.5196.0,将java的jar包转换为.dll控件,以使.NET可以使用

    解压ikvmbin ,并将%IKVM_HOME%\bin添加到path中。此处的%IKVM_HOME%是指解压后ikvm的主目录。...Java类或包文件的名字可以含有通配符(如*.class)。 参数----参数说明 -out:输出文件----指定输出文

    wildcard_attacks(利用SQL通配符进行DOS攻击)

    为了防范这类攻击,开发者应当注意限制搜索查询中的通配符使用,实施严格的输入验证和过滤策略,并考虑使用参数化查询或存储过程来减少潜在的安全风险。此外,定期对应用程序进行安全审计和渗透测试也是十分必要的,...

    SQL 通配符DOC版

    SQL 通配符是数据库查询中的重要工具,用于在 WHERE 子句中匹配不完全确定的数据。它们在配合 LIKE 运算符使用时,能够帮助用户模糊搜索数据库中的记录,适用于那些不知道确切值但知道部分信息的情况。在 SQL 中,...

    易语言文本实现匹配通配符

    3. **遍历文本与模式**:在函数内部,我们可以使用循环结构遍历文本和通配符,逐个字符进行比较。对于星号,需要考虑匹配多个字符的情况,可能需要嵌套循环;对于问号,只需匹配单个字符。 4. **特殊处理**:处理...

    SQL 通配符

    虽然通配符搜索非常方便,但它们可能对性能产生负面影响,尤其是当处理大量数据时。因为它们通常会导致全表扫描,而不是利用索引来快速定位数据。因此,在大型数据集上谨慎使用通配符。 6. **其他数据库系统的...

    IKVM7.3.4830.0,将java的jar包转换为.dll控件,以使.NET可以使用

    解压ikvmbin ,并将%IKVM_HOME%\bin添加到path中。此处的%IKVM_HOME%是指解压后ikvm的主目录。...Java类或包文件的名字可以含有通配符(如*.class)。 参数----参数说明 -out:输出文件----指定输出文

    SQL Server 2005 通配符及其意义

    在SQL Server 2005中,通配符是用于数据检索时匹配字符串模式的...因此,在进行大量数据的搜索时,应谨慎使用通配符,特别是当查询的效率是关键因素时。如果可能,尝试通过更具体的条件或使用全文搜索来优化查询性能。

    关于通配符的所有处理函数

    通配符是编程和数据库查询中非常常用的一种特殊符号,它们允许我们进行模糊匹配和模式查找,极大地提高了数据检索的灵活性。以下是对标题和描述中提及的通配符及其使用方法的详细说明: 1. `%` (百分号):这个...

    KMP.rar_KMP_KMP 串匹配_KMP 支持通配符

    总的来说,KMP算法是一种高效且实用的字符串匹配方法,尤其在处理大规模数据时,其优势更为明显。而通配符的支持则使得KMP算法具有更强的灵活性和实用性,能够满足更多样化的匹配需求。理解并掌握KMP算法及其通配符...

    PB动态检索 模糊查询 下接数据窗口 数据窗口 数据窗口

    模糊查询是在数据窗口中使用通配符进行的部分匹配搜索。在PB中,常见的通配符有`%`(代表零个、一个或多个任意字符)和`_`(代表一个任意字符)。例如,如果用户想要查找所有以“John”开头的名字,可以在查询条件中...

    java 通配符使用示例

    当方法参数使用通配符时,编译器可以根据上下文推断出具体的类型。 6. **实际应用** 在实际编程中,通配符广泛应用于集合框架,如List, Set, Map等,以及在多态方法和泛型方法的定义中。通过合理使用通配符,可以...

Global site tag (gtag.js) - Google Analytics