csdn0811 2024-05-25 22:14 采纳率: 60.7%
浏览 60

关于gorm 修改数据库的status值为0的问题!

使用gorm的Updates方法修改status值为0时,库中的status值不会改变,但修改为非0值时,数据库的status值可正常修改,为什么?

CREATE TABLE `access` (
  `id` int NOT NULL AUTO_INCREMENT,
  `module_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '0',
  `type` tinyint(1) DEFAULT NULL,
  `action_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `url` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `module_id` int DEFAULT NULL,
  `sort` int DEFAULT NULL,
  `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `status` int DEFAULT NULL,
  `add_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
);

type Access struct {
    Id          int
    ModuleName  string  
    Type        int      
    ActionName  string    
    Url         string   
    ModuleId    int       
    Sort        int  
    Description string  
    Status      int     
    AddTime     time.Time 
    AccessItem []Access `gorm:"foreignkey:ModuleId;references:Id"` // 子节点,关联自身表;
}

func main() {
    access := model.Access{
        Status: 0,
    }
    err := dao.Mdb.Model(&model.Access{}).Where("id = ?", 81).Updates(access).Error
    if err != nil {
        fmt.Println("修改失败", err)
    } else {
        var status int
        e := dao.Mdb.Model(&model.Access{}).Select("status").Where("id = ?", 81).First(&status).Error
        if e != nil {
            fmt.Println("查询失败:", e)
            return
        }
        fmt.Println("status:", status)
    }
}

奇怪的是使用原生sql可以正常修改数据库中的status值为0,为什么呢?

access := model.Access{
        ModuleName:  moduleName,
        Type:        accessType,
        ActionName:  actionName,
        Url:         url,
        ModuleId:    moduleId,
        Sort:        sort,
        Description: description,
        Status:      status,
        AddTime:     time.Now(),
    }
err := dao.Mdb.Exec("update access set module_name = ? , type = ? , action_name = ? , url = ? , module_id = ? , sort = ? , description = ? , status = ? , add_time = ? where id = ?", access.ModuleName, access.Type, access.ActionName, access.Url, access.ModuleId, access.Sort, access.Description, access.Status, access.AddTime, id).Error


  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-05-25 22:14
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的信息,看起来在使用 Gorm 的 Updates 方法更新 Status 字段为 0 时存在问题。这可能是因为 Gorm 在处理默认值为 0 的字段时存在一些优化,它可能会跳过设置值为默认值的操作。

    解决这个问题的一种方式是在更新前先检查当前记录的 Status 值是否为 0,如果是,则手动将其设置为一个非零值,例如 -1,然后再进行更新。这样,在执行更新操作时,Gorm 就会把 Status 更新为新的非零值,然后在回滚时再将它改回 0。以下是修改后的代码示例:

    func main() {
        var existingAccess model.Access
        err := dao.Mdb.First(&existingAccess, "id = ?", 81).Error
        if err != nil {
            fmt.Println("获取现有访问权限失败", err)
            return
        }
    
        if existingAccess.Status == 0 {
            // 如果当前状态是0,先将其更改为-1,确保会被更新
            existingAccess.Status = -1
        }
    
        access := &model.Access{
            Status: 0,
        }
    
        err = dao.Mdb.Model(existingAccess).Update("Status", access.Status).Error
        if err != nil {
            fmt.Println("修改失败", err)
        } else {
            var status int
            e := dao.Mdb.Model(&model.Access{}).Select("status").Where("id = ?", 81).First(&status).Error
            if e != nil {
                fmt.Println("查询失败:", e)
                return
            }
            fmt.Println("status:", status)
        }
    }
    

    这段代码首先获取了要更新的记录,然后检查其 Status 是否为 0。如果是,就将其设置为 -1。接着,使用 Gorm 的 ModelUpdate 方法,只更新 Status 字段。这种方法应该能正确地将 Status 更新为 0。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月25日