gorm使用中遇到的坑点
1、如果模型有DeletedAt字段,它将自动获得软删除功能! 那么在调用Delete时不会从数据库中永久删除,而是只将字段DeletedAt的值设置为当前时间
db.Where("age = ?", 20).Delete(&User{ })
2、使用struct更新仅适用于非零值 警告:当使用struct更新时,FORM将仅更新具有非空值的字段 对于下面的更新,什么都不会更新为"",0,false是其类型的空白值
db.Model(&user).Updates(User{ Name: "", Age: 0, Actived: false})
3、Count方法不适合放在raw方法后面,否则将会出错
count:=0 db.Raw(sql).Count(&count) //正确的方法是 count:=0 db.Table("orders").Count(&count)
4、使用db.Model查询的时候遇到的问题
func GetUserInfo(selSql, whereSql string,resp interface{ }) error { if err := db.Model(&entity.UserInfo{ }). Select(selSql).First(resp,whereSql).Error; err != nil { return err } return nil }
当selSql为星号这个语句正常执行,但是当selSql不是"*"时则会出现以下错误:
SELECT address FROM `` WHERE (user_id = "b414c837ebc38db2b8a557bdeb19a819" and app_id = "100") LIMIT 1
可以看到表名字消失了,测试后发现Model不能这么用 5 源码:
if kind := results.Kind(); kind == reflect.Slice { isSlice = true resultType = results.Type().Elem() results.Set(reflect.MakeSlice(results.Type(), 0, 0)) if resultType.Kind() == reflect.Ptr { isPtr = true resultType = resultType.Elem() } }
if err := rows.Err(); err != nil { scope.Err(err) } else if scope.db.RowsAffected == 0 && !isSlice { scope.Err(ErrRecordNotFound) }
example:
gormClient.Table("contracts"). Where(whereSql). Find(&data).RecordNotFound()
使用gorm的RecordNotFound的时候需要特别注意,example的data不能是切片,当data为切片时,即使没有找到结果也不会返回ture 所以如果要使用RecordNotFound,则搭配First更合适一些 否则使用RowsAffected判断 6 关于更新数据库Created_at会被自动更新的问题
type Contract struct { gorm.Model UserName string ` json:"user_name"` Name string `json:"name"` ... }
使用上面结构体自动创建数据库时,创建的数据库是这样的结构 这就会产生问题,更新数据库时created_at和updated_at将会同时被更新 解决方式也很简单: 关于时区的坑: mysql设置中极有可能会是这样的: 这个时候如果使用gorm连接数据库 得到的时区是UTC就会导致每次数据库自动更新updated_at时,时间总是比实际时间早八个小时,这时候需要修改mysql的时区,修改完之后记得重启服务