前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis 查询时对通配符的处理

Mybatis 查询时对通配符的处理

作者头像
chenchenchen
发布2021-09-06 10:26:18
6.4K0
发布2021-09-06 10:26:18
举报
文章被收录于专栏:chenchenchen

Mybatis、MongoDB 或者 Solr 引擎在查询数据的时候,如果存在%_等通配符时,这些特殊符号都不会被作为字符串进行搜索,会导致查询不出数据或者查询出来的数据是不准确的,这个时候就需要对特殊字符进行转义。

例如:

代码语言:javascript
复制
<if test="name != null and name != ''" >
    AND content.name like CONCAT(#{name},'%')
</if>

按原先的预想是该字段会进行左匹配,但是如果入参name是%测试%,则实际上搜索的是全匹配搜索了带有测试的所有值。

原因就是使用 LIKE 关键字进行模糊查询时,%、下划线 和 [] 单独出现时,会被认为是通配符,所以需要进行转义,然后通过 ESCAPE 告诉数据库转义字符后的字符为实际值。

首先对关键字进行转义,使用 StringEscapeUtils 对 Java 中特殊字符进行转义,或者使用以下的工具类

代码语言:javascript
复制
/**
     * sql模糊搜索时,对查询字段作特殊处理
     * 通配符转义处理后,like 语句后面加上 ESCAPE '/'
     * @param s 需要转义的字符串
     * @return 返回转义后的字符串
     */
    public static String escapeQueryChars(String s) {
        if (StringUtils.isBlank(s)) {
            return s;
        }
        // 只需要转义/%_
        s = s.replaceAll("/", "//");
        s = s.replaceAll("%", "/%");
        s = s.replaceAll("_", "/_");
        return s;
        // 遍历每个字符,如果是特殊字符则在前面拼接/
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0; i < s.length(); i++) {
//            char c = s.charAt(i);
//            if (c == '%' || c == '_' || c == '/'
//                    || c == '\\' || c == '+' || c == '-' || c == '(' || c == ')'
//                    || c == ':' || c == '^'	|| c == '[' || c == ']' || c == '\"'
//                    || c == '{' || c == '}' || c == '~' || c == '*' || c == '?'
//                    || c == '|' || c == '&' || c == ';' || c == '.'|| c == '!'
//                    || c == '$' || Character.isWhitespace(c)
//            ) {
//                sb.append('/');
//            }
//            sb.append(c);
//        }
//        return sb.toString();
    }

在 mabatis 的 mapper 文件中,在 like 语句后面加上 ESCAPE,告诉数据库转义字符为 “/”,转义字符后面的 % 或_就不作为通配符使用

代码语言:javascript
复制
like CONCAT(#{name},'%') ESCAPE '/'

也可以使用内置函数来进行模糊搜索 (locate () 等)

1、使用 locate ()

select `name` from `user` where locate('keyword', `condition`)>0

找到返回的结果都大于 0,没有查找到返回 0;

2、使用 instr ()

select`name` from `user` where instr(`condition`, ‘keyword’ )>0

唯一不同的是查询内容的位置不同

3、使用 position ()

select`name` from `user` where position(‘keyword’ IN `condition`)

4、使用 find_in_set ()

find_in_set (str,strlist),strlist 必须要是以逗号分隔的字符串

参考:

mybatis 对特殊字符的模糊查询:https://blog.csdn.net/wslyk606/article/details/85321759

mybatis 模糊查询特殊字符的处理:https://www.baidu.com/link?url=vVdwynxLrMPE-WMbEROJ5PrwhIv9V8pLm7h9dgu8JzmxVP4ulUv5hqIOuNFMWsaoeNGxIIpyuMsijxnAovLp2a&wd=&eqid=f256af3a000133a6000000065fa3e6eb

MyBatis 模糊查询特殊字符无效问题:https://baijiahao.baidu.com/s?id=1649824285248362226&wfr=spider&for=pc

Java 特殊字符转义:https://blog.csdn.net/weixin_40584261/article/details/88756970

MYSQL escape 用法 -- 转义:https://www.cnblogs.com/YuyuanNo1/p/12921578.html

使用 StringEscapeUtils 对 Java 中特殊字符进行转义和反转义:https://www.baidu.com/link?url=htBcQCkaqbCnnarInkA3l_FmM_vO_wtnRh9P70HI2d37TNkya6Xin1Pirfrx7XSyrJVrcpjelz-RWgG_MNTB1K_SLVqP1W-Owg73R3v4XhS&wd=&eqid=c063a264000b95d2000000065fa4ac17

常用工具类 StringEscapeUtils:https://my.oschina.net/mousai/blog/88832

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档