模糊查询使用%和_特殊符号进行查询

76 阅读2分钟

##模糊查询使用%和_特殊符号进行查询的解决方法

1、背景:

因为%以及_在数据库查询中本身就是在进行模糊查询,如果查询条件包含%以及_,会使SQL失效,因此需要进行转义处理,以下是关于如何处理的说明。

2、处理思路:

将含有特殊符号的查询条件按照特殊字符拆分后拼接上转义字符,并在SQL语句中使用 escape 关键字声明转义字符,

3、代码处理:

使用代码按照特殊字符进行拆分时因为不确定特殊字符的位置,所以需要区分三种情况: 1、查询条件以特殊字符结尾的,因为特殊字符后面没有内容,不会进行拆分,所以不需要再去掉末尾的字符; 2、查询条件仅包含特殊字符的,直接按照字符个数拼接转义符号; 3、查询条件开始或者中间位置是特殊字符的,按照正常拆分数量拼接转义符号.

/**
     * 对包含% 或者_特殊字符的数据增加转义符号.
     */
    public static String transContainsSpeChar(String data,String speChar){
        StringBuilder builder = new StringBuilder();
        String[] split = data.split(speChar);
        //根据特殊字符查分,拼接转义字符
        for (int i = 0; i < split.length; i++) {
            builder.append(split[i]).append("\\").append(speChar);
        }
        //以特殊字符结尾不需要删除末尾字符串
        if (!data.endsWith(speChar)){
            builder.delete(builder.length() - 2, builder.length());
        }
        //仅包含特殊字符
        if(isAllSpeChar(data,speChar)){
            for (int i = 0; i < data.length(); i++) {
                builder.append("\\").append(speChar);
            }
        }
        return builder.toString();
    }

    /**
     * 判断字符串是否只包含 %或者 _.
     */
    public static boolean isAllSpeChar(String str,String speChar) {
        String patStr = "^"+speChar+"+$";
        return str.matches(patStr);
    } 

4、SQL语句处理:

查询SQL中需要使用 escape 关键字声明使用了哪字符作为转义字符,以oracle数据库使用 "" 作为转义字符为例;在查询条件后面 增加 escape '' 语句就可以了

<if test="record.name != null and record.name != '' and (record.name.contains('%'.toString()) or record.name.contains('_'.toString())) ">
    and c.name like CONCAT(CONCAT('%',#{record.name,jdbcType=VARCHAR}),'%') escape '\'
    </if>
    <if test="record.name != null and record.name != '' and !(record.name.contains('%'.toString()) or record.name.contains('_'.toString())) ">
    and c.name like CONCAT(CONCAT('%',#{record.name,jdbcType=VARCHAR}),'%')
    </if>

5、针对不同数据库的说明:

以Oracle和MySQL为例(其他数据库类似): Oracle中没有默认的转义字符,所以查询条件中都需要使用 escape 关键字声明使用了什么字符作为转义字符, 例如:

SELECT * FROM CONTRACT WHERE NAME LIKE  '%\%%' escape '\' ;

MySQL中已经设置了默认的转义字符“\”,因此可以直接使用 “\”进行转义,不需要再进行声明,相反这个时候再重复声明会报错。 使用 escape 可以声明其他字符作为转义符号 例如:

SELECT * FROM CONTRACT WHERE NAME LIKE  '%@%%' escape '@' ;