一 背景
在用go语言开发项目的过程中,踩了一些坑,在这里做个记录。
二 踩坑记录
1 go语言反序列化切片提示错误【Cannot unmarshal string into Go value】
1⃣️排查过程
我是想把接受的前端参数string反序列化成StructList,结果一直报Cannot unmarshal string into Go value错。代码也很简单
var competitionEntriesList []*request.CompetitionEntriesRequest
err := json.Unmarshal([]byte(competitionEntries), &competitionEntriesList)
if err != nil {
logs.CtxError(req.GinContext, "Unmarshal competitionEntries error:%+v", err)
return nil, errors.New("参数格式错误")
}
拥有质疑精神的我以为不能把string反序列化成指针数组。所以把指针去掉了,不过反序列化时候还是有问题,在网上试着搜索下反序列化切片。结果都是这样的,这是欺负我刚从java转成go么?欺负我map和slice傻傻分不清?
抄袭太严重了,淦!后来经过同事帮助发现了问题。比较奇怪的是你自己怎么看都看不出来小问题,别人一看就知道问题出在哪里。
2⃣️问题结论
其实错误提示已经很明显了,该字符串不能反序列化。甚至debug的时候如果仔细观察可以观察到多了个引号,原因就是我用在线字符串格式化把参数多加了个双引号,然后把参数放在了postman里进行调用。
相信已经发现了问题。在postman进行测试的时候不需要自己去多加【引号】,postman会自带上的。以后使用的时候需要注意。上面的使用姿势也是没有问题的
2 err: %!(EXTRA *mysql.MySQLError=Error 1105: prepare error ERROR 1054 (42S22): Unknown column 'field list')
1⃣️排查过程
这个问题是在用gorm框架执行更新数据库操作的时候出现了这个错误。去网上百度/谷歌的内容也是不尽相同,得出的结论就是数据库和dto的映射关系对应不上,后来通过debug发下是有个字段的格式对不上
2⃣️问题结论
正确的使用姿势
定义orm对应的结构体
type Test struct {
Id int64 `gorm:"primary_key"`
Uid int64
CreateTime time.Time
ModifyTime time.Time
}
// 定义结构体对应的表
func (Test) TableName() string {
return "test"
}
// 执行插入操作
test := &Test{
Uid: 10086,
CreateTime: time.Now(),
ModifyTime: time.Now(),
}
result := db.Create(test)
3 err: return err' err=record not found
1⃣️排查过程
在查询数据库数据的时候出现了这个错误,这个错误通过以往代码的使用姿势和网上资料发现了结论,
用Struct接受返回值的时候如果没有查到信息,会抛出【gorm.ErrRecordNotFound】的错误
用StructList接受返回值的时候如果没有查到信息,不会抛错误。
使用的时候需要注意下,详细的解释可以参考下这篇文章:GORM最佳实践之ErrRecordNotFound的坑
2⃣️问题结论
正确的使用姿势
var designerCompetitionApply DesignerCompetitionApply
result := db.Where("uid = ?", userId).First(&designerCompetitionApply)
if result.Error != nil {
if gorm.ErrRecordNotFound == result.Error {
return nil, nil
} else {
return nil, result.Error
}
}
return &designerCompetitionApply, nil