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
相关产品推荐
相关产品推荐

