Laravel使用selectRaw查询返回JSON列被转义为字符串如何解决
问题原因
你当前通过CONCAT拼接生成的结果本质是普通字符串类型,MySQL不会自动将其识别为JSON格式,因此应用层拿到该字段后会当做普通字符串处理,序列化输出时就会自动转义内部的双引号,最终得到你看到的带转义的结果。
解决方案
方案1:查询阶段直接转换为JSON类型(推荐)
如果你的MySQL版本 >= 5.7,直接用CAST函数将拼接结果显式转换为JSON类型即可,修改你的查询语句为:
$results->selectRaw("CAST(CONCAT('[',GROUP_CONCAT(JSON_OBJECT('value', measured_at, 'day', datediff(measurements.measured_at, athletes.tracking_started_at))), ']') AS JSON) as `values`");
如果你的MySQL版本 >= 5.7.22或使用8.0版本,可以直接使用内置的JSON_ARRAYAGG函数生成JSON数组,无需手动拼接,还能避免GROUP_CONCAT默认长度限制导致的数据截断问题:
$results->selectRaw("JSON_ARRAYAGG(JSON_OBJECT('value', measured_at, 'day', datediff(measurements.measured_at, athletes.tracking_started_at))) as `values`");
注意:手动使用
GROUP_CONCAT拼接时要注意MySQL默认的group_concat_max_len配置限制,数据量较大时可能会出现内容截断,更推荐使用JSON_ARRAYAGG的方案。
方案2:应用层做类型转换
如果你使用的是Laravel框架(从你使用的selectRaw语法判断),可以直接在对应模型的$casts属性中声明字段类型,框架会自动完成字符串到JSON结构的转换:
// 对应模型文件中添加以下配置 protected $casts = [ 'values' => 'array' ];
配置后即使查询返回的是字符串格式的JSON,Laravel也会自动执行json_decode操作,序列化输出时会直接返回标准JSON数组,不会出现转义字符。
内容的提问来源于stack exchange,提问作者reans
相关产品推荐
相关产品推荐

