【MYSQL】解决模糊查询含有关键字的问题

前言

下面讲了关于模糊查询条件中含有通配符关键字的问题,但是对于含有转义字符的问题没有提及,如果想了解转义字符的问题,请参考链接:【MYSQL】MYSQL转义字符带来的坑。

一、问题分析

假如你有一张表 user_info:

idaddress
1浙江省杭州市
2浙江省舟山市
3浙江省xx%市
4浙江省宁波市

如果页面需要根据地址进行模糊查询,但是sql语句如下:

select 
	id, address
from 
	user_info
where
 	address like concat('%', #{condition}, '%')	

我们想查询地址中含有%的数据,如果condition输入的是 '%',期望是查询id=3的数据,结果是查询的全表的数据:

select id, address from user_info where address like '%%%'; -- 查询的是全表

所以使用concat函数在实现模糊查询时,查询条件中含有通配符会存在问题。跳转到concat函数用法

二、解决办法

1. 解决方式1

如果需要仍然使用concat拼接字符串的方式,则需要将拼接的字符串进行转义,出现问题的原因就是查询的字符串中含有关键字%,导致sql查询有问题。
所以当需要模糊查询时,需要处理查询条件中的通配符关键字

	// 转义condition中的通配符
	public static String escapeCondition(String condition) {
        if (condition == null || condition.length() <= 0) {
            return condition;
        }
        StringBuilder ans = new StringBuilder();
        for (char c : condition.toCharArray()) {
            if (c == '%' || c == '_' || c == '\\') {
                // 如果当前字符是关键字符,则添加转义字符
                ans.append("\\");
            }
            ans.append(c);
        }
        return ans.toString();
    }
# 将查询条件的%进行转义,加上\后,sql如下
select id, address from user_info where address like '%\%%'; -- 能够正确将id=3的结果查询出来

PS: 如果不喜欢使用\字符进行转义, 也可以使用escape关键字来自定义转义字符。跳转到escape关键字用法

2. 解决方式2

可以使用INSTR函数替代concat函数实现模糊查询
INSTR(str, subStr): 是返回子字符串(subStr)在目标字符串(str)的位置。(不区分大小写)

select INSTR('Hello World', 'he'); -- 返回结果是 1
select INSTR('Hello World', 'Hex'); -- 返回结果是 0

所以上面的写法可以改写为如下,就可以实现模糊查询:

select 
	id, address
from 
	user_info
where
	INSTR(address, #{condition})

三、函数用法

  1. concat函数用法
    mysql用法:CONCAT(str1,str2,…), 将指定的若干字符串拼接在一起
    # mysql的concat用法
    select CONCAT('12','34','56','7');  -- 结果为 '1234567'
    # mysql中只要有一个为null,整个结果都是null
    select CONCAT('12','34','56', null, '7'); --结果为null
    
    oracle用法:CONCAT(str1,str2),和mysql中不同的是,oracle中concat只能拼接两个字符串,如果要想拼接多个,只能使用嵌套的方式。
    # oracle的concat用法
    select CONCAT('12', '34') from dual;  -- 结果为 '1234'
    select CONCAT('12', null) from dual;  -- 结果为 null
    # oracle嵌套拼接多个字符
    SELECT CONCAT(CONCAT('12', '34'), '56') FROM dual; -- 结果为 '123456'
    
  2. escape关键字用法
    在mysql中,使用escape关键字用于指定一个转义字符,在使用like操作符处理通配符%_时,能够区分他们作为普通字符还是作为通配符使用,在默认情况下,mysql使用反斜杠 \作为转义字符,但是可以通过escape关键字自定义转义字符。
    # 默认情况下使用\作为转义字符
    select id, address from user_info where address like '%\%%';
    # 想使用 ^ 作为转义字符, 和上面的sql效果相同
    select id, address from user_info where address like '%^%%' ESCAPE '^';
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值