You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL存储Unicode及特殊字符问题:escapeJava转义后存储异常致解码失败

解决MySQL存储Unicode转义字符丢失反斜杠的问题

嘿,这个坑我之前踩过!你遇到的问题本质是MySQL默认会把反斜杠\当作SQL转义字符,导致你用StringEscapeUtils.escapeJava()生成的\uxxxx格式字符串存进数据库后,反斜杠被吃掉,只剩下uxxxx,自然unescapeJava()解码失败。

问题根源

MySQL默认的sql_mode中没有启用NO_BACKSLASH_ESCAPES,这意味着它会解析字符串中的反斜杠,把它当作转义标记。比如你存入\u0022(双引号的Unicode转义),MySQL会认为你想转义后面的u,但u不是特殊转义字符,所以直接丢弃反斜杠,最终存储的内容变成u0022。

解决方案

方案1:修改MySQL连接参数(推荐)

在你的JDBC URL中添加sessionVariables=sql_mode='NO_BACKSLASH_ESCAPES',让MySQL不再处理反斜杠作为转义字符。示例URL:

jdbc:mysql://localhost:3306/your_db?useSSL=false&characterEncoding=UTF-8&sessionVariables=sql_mode='NO_BACKSLASH_ESCAPES'

这样设置后,你直接用StringEscapeUtils.escapeJava()转义后的字符串存入数据库,反斜杠会被完整保留,读取后用unescapeJava()就能正常解码。

方案2:手动双重转义反斜杠

如果无法修改连接参数,可以在转义后把反斜杠再转义一次,让MySQL存完后保留单个反斜杠:

String rawContent = "包含\"双引号和Unicode的内容";
// 先转义特殊字符为\uxxxx格式
String escaped = StringEscapeUtils.escapeJava(rawContent);
// 把每个\替换成\\,这样MySQL会把\\解析成单个\
String doubleEscaped = escaped.replace("\\", "\\\\");
// 存入数据库的是\\uxxxx,读取后变成\uxxxx,可正常解码

方案3:全局设置MySQL的sql_mode

如果你有权限修改MySQL配置,可以在my.cnf(或my.ini)中添加:

sql_mode = NO_BACKSLASH_ESCAPES

重启MySQL后,所有连接都会生效,不需要修改代码或连接参数。

注意事项

  • 如果你使用NO_BACKSLASH_ESCAPES,SQL中的单引号需要用两个单引号''来转义,而不是\',不过如果用PreparedStatement做参数化查询,这个问题会被自动处理,不用担心SQL注入。
  • 优先推荐方案1,因为它不需要修改业务代码,配置一次即可生效,避免手动转义带来的潜在错误。

内容的提问来源于stack exchange,提问作者Prashant Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:06:08