解决mysql 模糊搜索特殊符号导致查询不正确问题

当我们在使用mybatis做模糊查询时,有两个特殊符号需要注意:

%(百分号):相当于任意多个字符;

_(下划线):相当于任意的单个字符;

解决方案就是将特殊符号加转义字符

 public static String escapeChar(String string) {
        if (StringUtils.isNotBlank(string)) {
            string = string.replaceAll("_", "/_");
            string = string.replaceAll("%", "/%");
        }
        return string.trim();
    }

将传进来的参数做替换。

 这里表示我们转义字符是/,也可以自定义其它符号,匹配上即可。

现在虽然解决的查询问题,但是每个方法我们都要都要根据不同的字段做相应处理,要是方法或者字段多的话就非常麻烦,所以我想着用过滤器来解决问题,在传进来的参数和字段做匹配后自动转义。

自定义ParameterRequestWrapper继承HttpServletRequestWrapper,获取请求参数和做参数替换。

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> params = new HashMap<>();

    public ParameterRequestWrapper(HttpServletRequest request) {
        // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
        super(request);
        //将参数表,赋予给当前的Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
    }

    public ParameterRequestWrapper(HttpServletRequest request, Map<String, Object> extendParams) {
        this(request);
        addAllParameters(extendParams);
    }

    public Map<String, String[]> getParameterMap() {
        return params;
    }

    public Enumeration getParameterNames() {
        Vector l = new Vector(params.keySet());
        return l.elements();
    }


    @Override
    public String getParameter(String name) {
        String[] values = params.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    public String[] getParameterValues(String name) {
        return params.get(name);
    }

    public void addAllParameters(Map<String, Object> otherParams) {
        for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
            addParameter(entry.getKey(), entry.getValue());
        }
    }


    public void addParameter(String name, Object value) {
        if (value != null) {
            if (value instanceof String[]) {
                params.put(name, (String[]) value);
            } else if (value instanceof String) {
                params.put(name, new String[]{(String) value});
            } else {
                params.put(name, new String[]{String.valueOf(value)});
            }
        }
    }

    public void removeParameter(String name) {
        if (params.get(name) != null) {
            params.remove(name);
        }
    }
}

自定义过滤器SpecialSymbolsFilter 继承 OncePerRequestFilter

@Component
@WebFilter(filterName = "handleFilter", urlPatterns = "/*")
public class SpecialSymbolsFilter extends OncePerRequestFilter {

    /**
     * 特殊符号
     */
    private static final String[] SPECIAL_SYMBOLS = {"%", "_"};

    /**
     * 过滤的字段
     */
    private static final String[] FILTER_FIELDS = {"name","equipName","stationName"};

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        ParameterRequestWrapper parameterRequestWrapper = new ParameterRequestWrapper(request);
        for (String filterField : FILTER_FIELDS) {
            for (String specialSymbol : SPECIAL_SYMBOLS) {
                String parameter = parameterRequestWrapper.getParameter(filterField);
                if (StringUtils.isNotNull(parameter)) {
                    if (parameter.contains(specialSymbol)) {
                        parameterRequestWrapper.addParameter(filterField, escapeChar(parameter));
                    }

                }

            }
        }
        filterChain.doFilter(parameterRequestWrapper, response);

    }

    public static String escapeChar(String string) {
        if (StringUtils.isNotBlank(string)) {
            string = string.replaceAll("_", "/_");
            string = string.replaceAll("%", "/%");
        }
        return string.trim();
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_38982591/article/details/128326930
今日推荐