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

MySQL使用JSON_SET存入Java序列化的list、HashMap等JSON结构失败问题求助

问题原因

你遇到的问题由两个核心原因导致:

  1. 直接拼接Gson序列化输出的JSON字符串时,JSON内部的双引号会和SQL语法冲突,直接触发语法错误导致执行失败。
  2. 给JSON字符串外层加单引号后,MySQL会将整个串识别为普通字符串字面量,存入JSON字段时会自动转义为字符串值,而非嵌套的JSON对象/数组结构,后续自然无法直接解析为List或HashMap。

解决方法

方法1:调整拼接逻辑(临时快速解决,不推荐,存在SQL注入风险)

将序列化后的JSON字符串通过CAST函数显式转换为JSON类型,同时转义JSON内部的单引号避免语法冲突:

String jsonValue = this.gson.toJson(value);
// 转义JSON中的单引号避免SQL语法错误
jsonValue = jsonValue.replace("'", "\\'");
String query = "UPDATE `users` SET `data` = JSON_SET(`data`, '$." + fieldName + "', CAST('" + jsonValue + "' AS JSON)) WHERE `userid` = '" + userId + "';";

方法2:使用预编译语句(强烈推荐)

完全放弃SQL拼接,使用JDBC的PreparedStatement做参数绑定,既杜绝SQL注入风险,也不需要手动处理转义,MySQL驱动会自动处理类型转换:

String sql = "UPDATE `users` SET `data` = JSON_SET(`data`, ?, CAST(? AS JSON)) WHERE `userid` = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    // 绑定JSON路径参数
    pstmt.setString(1, "$." + fieldName);
    // 绑定序列化后的JSON内容
    pstmt.setString(2, this.gson.toJson(value));
    // 绑定用户ID参数
    pstmt.setString(3, userId);
    pstmt.executeUpdate();
}

验证方式

存入后执行如下查询校验类型是否正确,若返回ARRAY/OBJECT说明存储成功,返回STRING则说明还是存为了普通字符串:

SELECT JSON_TYPE(`data`->'$.你存入的字段名') FROM `users` WHERE `userid` = 1;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:24:03