MySQL使用JSON_SET存入Java序列化的list、HashMap等JSON结构失败问题求助
问题原因
你遇到的问题由两个核心原因导致:
- 直接拼接Gson序列化输出的JSON字符串时,JSON内部的双引号会和SQL语法冲突,直接触发语法错误导致执行失败。
- 给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
相关产品推荐
相关产品推荐

