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

GORM关联查询中datatype.JSON字段解析多余双引号问题

解决GORM查询转ModelB时f6字段出现多余双引号的问题

问题出在你从map中获取的f6值是带转义的字符串类型JSON,而非原始的JSON值。当你通过json.Marshal再json.Unmarshal的过程,相当于对这个字符串做了二次JSON序列化,最终导致出现多余的双引号。

根本原因

数据库中ModelBRepo的f6是datatype.JSON类型,存储的是原始JSON数据(比如"TEST"或["TEST1","TEST2","TEST3"])。但通过关联查询存入map[string]interface{}后,res[0][mb_f6]的实际类型是Go字符串,值为转义后的JSON(比如原始JSON是"TEST",map中就变成了"\"TEST\"")。

当你执行json.Marshal(mapB)时,这个字符串会被再次JSON序列化——给整个字符串套上双引号并转义内部的引号,变成"\"\\\"TEST\\\"\"";随后json.Unmarshal解析到any类型的mb.f6时,就得到了带双引号的字符串"\"TEST1\"",打印出来就是""TEST1""。

三种解决方法

1. 先解析map中的f6字符串为原始JSON值

在构建mapB前,先把map中带转义的f6字符串解析成原始JSON值:

mapB := map[string]interface{}{
    "f4": res[0][mb_f4],
    "f5": res[0][mb_f5],
}

// 单独处理f6字段
if f6Str, ok := res[0][mb_f6].(string); ok {
    var rawF6 any
    if err := json.Unmarshal([]byte(f6Str), &rawF6); err == nil {
        mapB["f6"] = rawF6
    }
}

var mb ModelB
b, _ := json.Marshal(mapB)
json.Unmarshal(b, &mb)

这样mb.f6就会得到原始的"TEST1"或数组值。

2. 跳过JSON序列化,直接给ModelB字段赋值

既然已经有了map中的数据,直接手动赋值更高效,避免二次序列化的问题:

var mb ModelB
mb.f4 = res[0][mb_f4].(string)

// 处理指针类型的f5
if f5Val, ok := res[0][mb_f5].(*string); ok {
    mb.f5 = f5Val
}

// 处理f6
if f6Str, ok := res[0][mb_f6].(string); ok {
    json.Unmarshal([]byte(f6Str), &mb.f6)
}

3. 直接用GORM查询到ModelBRepo再转换

从根源避免map的转义问题:用GORM直接查询ModelBRepo实例,它的f6字段是datatype.JSON类型,GORM会自动解析成原始JSON值,再直接赋值给ModelB:

var mbRepo ModelBRepo
// 替换成你的查询条件
db.Model(&ModelBRepo{}).Where("id = ?", xxx).First(&mbRepo)

var mb ModelB
mb.f4 = mbRepo.f4
mb.f5 = mbRepo.f5
mb.f6 = mbRepo.f6 // datatype.JSON可直接赋值给any类型
mb.mAID = mbRepo.mAID
// 其他继承自BaseRepository的字段按需赋值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:40:18