mysql replace 斜杠_检查MySQL问题的步骤。震惊!like要4个斜杠当作一个斜杠

哇我之前一个项目中做了两个功能,一个是用到sql的like的,一个是用到=的,都是字符串匹配,我感觉应该很无敌。

结果被人发现用带有“\\n”的语句,在like的时候能匹配到有“\n”的语句,是他们想要的结果。但是在用=的时候就匹配不到东西。哇就说我的功能有问题,我只好看一看怎么回事。

下面开始检查问题。

1.先开一个mysql控制台,用最基本的sql语句试一试。发现like的要写like "%\\\\n%"才能匹配“\n”(是一个杠加一个n,不是换行符)。然后=的要写\\n能匹配到。好像和服务端的情况不太一样,上面说的现象是like用两个斜杠能匹配到啊,这里要四个斜杠。

2.开一下mysql的log,看一下我写的模块生成了什么样的sql语句。

在mysql控制台 输入

set global general_log=on;

开启log,然后看一下log在哪:

mysql> show variables like 'datadir';

+---------------+---------------------------------------------+

| Variable_name | Value |

+---------------+---------------------------------------------+

| datadir | C:\ProgramData\MySQL\MySQL Server 5.7\Data\ |

+---------------+---------------------------------------------+

1 row in set, 1 warning (0.00 sec)

mysql> show variables like "%log_file%";

+---------------------------+---------------------+

| Variable_name | Value |

+---------------------------+---------------------+

| general_log_file | xxx6.log |

| innodb_log_file_size | 50331648 |

| innodb_log_files_in_group | 2 |

| slow_query_log_file | xxx6-slow.log |

+---------------------------+---------------------+

4 rows in set, 1 warning (0.00 sec)

哇,就能开心地去看log了。里面会写有执行的语句。这时自己调试一下,让服务端发一个带\\n的like过去。发现到sql这边已经变成\\\\n了,看来是hibernate帮搞了一搞。

然后就应该测一下服务端发个带\\n的=过去看看,果然匹配不到。发个带\n的就能正确匹配了。哇那这不就很稳?\n匹配\n很正确啊,用户想拿\\n来想匹配\n是不是用法有问题啊……这个到时候再说。看log是hibernate已经帮把sql语句变成了\\n。

3.去mysql官网找说明,看看为啥会这样。官网说了一堆废话:

Note

Because MySQL uses C escape syntax in strings (for example, \n to represent a newline character), you must double any \ that you use in LIKE strings. For example, to search for \n, specify it as \\n. To search for \, specify it as \\\\; this is because the backslashes are stripped once by the parser and again when the pattern match is made, leaving a single backslash to be matched against.

实际上从LIKE的用法来看,就可以知道为什么。因为LIKE要用到%来代表任意字符串,所以需要用\%来表示真正的百分号,“\”要在like里充当许多东西的转义符。所以就是那种,再转了一层的感觉,在一般的sql字符串里“\\”就代表一个斜杠了,在LIKE里就要“\\\\”才行。

4.那要如何让like和不like两边的表现一致呢?现在在一般情况下是\n能匹配\n,在like下是\\n匹配\n,很奇怪。这是因为我在like那边是用"%"+str+"%"来简单拼出来了一个like字符串,没有对中间的str做处理。

这个地方的需求是:找到包含str子串的项。但是好像并没有简单实现这一简单需求的方法……网上的方法和我这个一样,在两边加百分号,中间不转义,有下划线、这个斜杠之类的就会有问题。很神秘,难道我只能自己转义一下了吗?

于是我自己转义了一下:

import com.dyf.i18n.util.ListStringUtil;

import com.dyf.i18n.replace.QuickReplacer;

import com.dyf.i18n.replace.Replacer;

// String[] likeReplaceKeys = {"\\", "%", "_", "["};

String[] likeReplaceValues = {"\\\\", "\\%", "\\_", "\\["};

Map sqlLikeReplaceMap = ListStringUtil.array2map(likeReplaceKeys, likeReplaceValues);

Replacer sqlLikeReplacer = new QuickReplacer(sqlLikeReplaceMap);

//以上是准备工作,做一次就行,下面的每次要转义的时候调用 String likeStr = "%" + sqlLikeReplacer.doReplace(inputStr) + "%";

哇,是不是感觉,怎么这么简单就能做超碉的多组字符串替换了!用到的传说中的com.dyf.i18n库到底哪里能下到呢!就在:Yuiffy/excel-translation-to-i18n-files

https://github.com/Yuiffy/excel-translation-to-i18n-files/blob/dev/src/main/java/com/dyf/i18n/util/ListStringUtil.java

哇,结束。这样就解决了一大业务难题,我自己都害怕,是不是适合涨工资。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值