202111-22更文-mysql查询时特殊字符的处理

884 阅读2分钟

这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

mysql查询时特殊字符的处理

前文

本文主要为最近开发过程中出现了一个查询bug,也就是当查询时将mysql的特殊字符作为条件传递给数据库进行模糊查询时,会出现查询数据结果与实际结果不匹配的问题。在此将解决方案进行记录,并非最佳方案,不正确之处还请指正。

问题描述

最近在开发一个功能时,存在一个模糊查询的需求,根据描述的部分内容模糊查询匹配。正常的查询条件输入正常,但是当输入%、_等特殊字符时,会出现查询部分或全部的异常结果。

问题分析及解决

遇到这个为题,首先探索了在MySQL中,%、_等特殊字符的含义具体是什么。百分号作为特殊字符表示为模糊查询,而下划线表示匹配任意一个字符。先看一下问题的现象:

SELECT
	sd.description
FROM
	sys_dict sd
	JOIN sys_dict_type sdt ON sd.type_id = sdt.ID 
WHERE
	sd.del_flag = 0 
	AND sd.description LIKE'%' ||'_'|| '%'

当利用上述语句查询包含下划线的描述时,出现的结果为全部数据:

image.png 很明显,由于特殊字符的存在,数据库将其认为是依据特殊字符的查询,而不是模糊匹配包含下划线字符的查询。很明显,想要解决这个问题,我们需要对数据库字符进行转义。而数据库的转移是利用反斜线,因此查询语句变为如下所示:

SELECT
	sd.description
FROM
	sys_dict sd
	JOIN sys_dict_type sdt ON sd.type_id = sdt.ID 
WHERE
	sd.del_flag = 0 
	AND sd.description LIKE'%' ||'\_'|| '%'

查询结果如下,很明显通过转移,下划线已经失去了作为特殊字符的意义,变为普通字符进行查询。 image.png 至此,问题可以说解决完毕。由于笔者所采用的项目为java语言开发,因此在此处增加以下java中对于特殊字符的操作。

if(sysDictTypeDTO.getType() != null){
        sysDictTypeDTO.setType(sysDictTypeDTO.getType().replaceAll("%","\\\\%").replaceAll("_","\\\\_"));
}

由于java中使用双斜线作为转义符,因此对数据的加工变成上面的形式。经过测试,问题解决。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。