当前位置: 首页 > news >正文

Gorm中的First()、Create()、Update()、Delete()的错误处理

一. First()

result := tx.Model(&models.Attachment{}).Where("home = ? AND home_id = ?", attachment.Home, attachment.HomeID).First(&existingAttachment)

如果没有查询到数据,result.Error的值是什么?

在使用 GORM(Go 的 ORM 框架)进行数据库操作时,result.Error 的值取决于查询的执行情况。
如果查询没有找到任何数据,result.Error 的值通常是 gorm.ErrRecordNotFound。

解释:

1.First 方法:First 方法会尝试获取查询结果的第一条记录。如果没有找到任何匹配的记录,GORM 会返回一个错误,通常是 gorm.ErrRecordNotFound。

2.result.Error:result.Error 是 GORM 的 Result 结构体中的一个字段,用于存储查询或操作过程中发生的错误。如果没有错误,它的值为 nil;如果有错误,它会包含具体的错误信息。

示例代码:

if result.Error != nil {if errors.Is(result.Error, gorm.ErrRecordNotFound) {// 没有找到数据fmt.Println("No record found")} else {// 其他错误fmt.Println("Error occurred:", result.Error)}
} else {// 查询成功,数据存储在 existingAttachment 中fmt.Println("Record found:", existingAttachment)
}
注意事项:
  • 如果你希望在没有找到数据时不返回错误,可以使用 Take 方法代替 First。Take 方法在没有找到数据时不会返回错误,而是将目标变量设置为默认值。
  • 如果你使用的是 GORM v2 或更高版本,gorm.ErrRecordNotFound 是一个常量错误,可以通过 errors.Is 来判断是否是“未找到记录”的错误。

二. Create()

// 向api表中添加api相关信息
err := tx.Model(models.Api{}).Create(&api).Error
if err != nil {
tx.Rollback() // 回滚事务
return fmt.Errorf("CreateApiRep -> 向api表中添加api相关信息失败 -> %s", err)
}

如果插入数据失败,err的值是什么?

在使用 GORM 的 Create 方法插入数据时,如果插入操作失败,err 的值将是一个具体的错误对象,其内容取决于失败的原因。这些错误通常是由数据库操作或约束违反引起的。以下是一些常见的错误类型及其可能的值:

1. 数据库约束违反

如果插入的数据违反了数据库的约束(如主键冲突、唯一约束冲突、外键约束等),err 的值通常是一个 *pq.Error(PostgreSQL)或 *mysql.MySQLError(MySQL)对象,具体取决于你使用的数据库驱动。

示例错误:
- 主键冲突(MySQL):
Error 1062: Duplicate entry '1' for key 'PRIMARY'- 唯一约束冲突(MySQL):
Error 1062: Duplicate entry 'example' for key 'unique_key_name'- 外键约束冲突(MySQL):
Error 1452: Cannot add or update a child row: a foreign key constraint fails
示例错误(PostgreSQL):
- 主键冲突:
pq: duplicate key value violates unique constraint "pkey_name"- 唯一约束冲突:
pq: duplicate key value violates unique constraint "unique_constraint_name"

2. 数据类型不匹配

如果插入的数据类型与数据库表定义不匹配(如字符串长度超出限制、字段类型不匹配等),err 的值通常是一个语法错误或类型错误。
示例错误(MySQL):

Error 1265: Data truncated for column 'column_name' at row 1

3. 数据库连接问题

如果数据库连接失败或超时,err 的值可能是一个连接错误。
示例错误:

dial tcp 127.0.0.1:3306: connect: connection refused

4. 其他错误

其他可能的错误包括:

  • SQL 语法错误
Error 1064: You have an error in your SQL syntax
  • 事务回滚错误
transaction is already rolled back

如何处理这些错误

在实际开发中,你可以根据错误类型进行相应的处理。以下是一些常见的处理方式:

示例代码:
err := tx.Model(models.Api{}).Create(&api).Error
if err != nil {tx.Rollback() // 回滚事务if gorm.IsRecordNotFoundError(err) {return fmt.Errorf("CreateApiRep -> 插入数据失败:记录未找到")} else if strings.Contains(err.Error(), "Duplicate entry") {return fmt.Errorf("CreateApiRep -> 插入数据失败:唯一约束冲突")} else {return fmt.Errorf("CreateApiRep -> 插入数据失败 -> %s", err)}
}

总结

  • err 的值取决于插入操作失败的具体原因。
  • 常见的错误类型包括数据库约束违反、数据类型不匹配、连接问题等。
  • 你可以通过检查错误消息或使用 GORM 提供的工具(如 gorm.IsRecordNotFoundError)来处理这些错误。

三. Update()

// 更新 api_group 表中的 group_id
resag := tx.Model(&models.ApiDictItemGroup{}).Where("api_id = ?", api.ID).Update("group_id", groupId)
if resag.Error != nil {
tx.Rollback() // 回滚事务
return fmt.Errorf("UpdateApiRep -> 更新 api_group 表中的 group_id失败 -> %s", resag.Error)
}

当更新的数据与原数据相同时,resag.RowsAffected的值是什么?

在 GORM 中,Update 方法的 RowsAffected 属性表示实际被更新的行数。如果更新的数据与原数据相同,RowsAffected 的值通常为 0,表示没有行被实际修改。

示例代码及解释

假设你有一个 ApiDictItemGroup 模型,并试图更新其 group_id 字段:

resag := tx.Model(&models.ApiDictItemGroup{}).Where("api_id = ?", api.ID).Update("group_id", groupId)
  • 如果
    groupId 与数据库中当前的 group_id 值相同
    • resag.Error 是 nil,表示没有错误。
    • resag.RowsAffected 的值为 0,因为没有实际修改任何行。
    • 数据库不会执行实际的更新操作,因为没有数据变化。
  • 如果
    groupId 与数据库中当前的 group_id 值不同
    • resag.Error 是 nil,表示没有错误。
    • resag.RowsAffected 的值为 1,因为有一行数据被修改。

结论

当你尝试更新的数据与原数据相同时,RowsAffected 的值为 0。这表明没有行被实际修改,但操作是成功的。

建议

如果你需要确保某些逻辑仅在数据实际更改时执行,可以检查 resag.RowsAffected 的值是否大于 0。例如:

if resag.RowsAffected > 0 {// 数据被实际修改,执行某些逻辑
}

四. Delete()

result2 := tx.Model(&models.ApiDictItemGroup{}).Where("api_id = ?", id).Delete(nil)
if result2.Error != nil {
tx.Rollback() // 回滚事务
return fmt.Errorf("DeleteApiRep ->  删除api_group表中的信息失败 -> %s", result2.Error)
}

如果要删除的数据不存在,result2.Error 的值是什么?

在 GORM 中,如果要删除的数据不存在(即删除条件未匹配到任何记录),result2.Error 的值通常为 nil,而不是一个具体的错误。这是因为 GORM 认为“未找到匹配记录”并不是一个错误,而是一个正常的操作结果。

在这种情况下,result2.RowsAffected 的值会是 0,表示没有行被删除。如果你需要根据是否删除了数据来判断操作是否成功,可以通过检查 result2.RowsAffected 来实现。

示例代码

result2 := tx.Model(&models.ApiDictItemGroup{}).Where("api_id = ?", id).Delete(nil)
if result2.Error != nil {tx.Rollback() // 回滚事务return fmt.Errorf("DeleteApiRep -> 删除api_group表中的信息失败 -> %s", result2.Error)
}if result2.RowsAffected == 0 {tx.Rollback() // 回滚事务return fmt.Errorf("DeleteApiRep -> 删除api_group表中的信息失败 -> 未找到匹配的记录")
}

总结

  • 如果删除条件未匹配到任何记录,result2.Error 的值是 nil。
  • 如果需要判断是否删除了数据,可以通过检查 result2.RowsAffected 是否为 0 来实现。
  • 如果 result2.Error 不为 nil,则表示删除操作失败,可能是由于其他错误(如数据库连接问题、SQL 执行错误等)。
http://www.lryc.cn/news/545658.html

相关文章:

  • 【心得】一文梳理高频面试题 HTTP 1.0/HTTP 1.1/HTTP 2.0/HTTP 3.0的区别并附加记忆方法
  • Navicat连接虚拟机数据库详细教程
  • 委托者模式(掌握设计模式的核心之一)
  • DeepSeek-R1 论文笔记:通过强化学习提升大语言模型的推理能力
  • 实现Unity shader扭曲效果
  • 七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)
  • C++STL---<limits>
  • 一键安装Mysql部署脚本之Linux在线安装Mysql,脚本化自动化执行服务器部署(附执行脚本下载)
  • ES、OAS、ERP、电子政务、企业信息化(高软35)
  • 文生图开源模型发展史(2014-2025年)
  • OA办公系统自动渗透测试过程
  • Python标准库【os】5 文件和目录操作2
  • [代码规范]接口设计规范
  • 什么是最终一致性,它对后端系统的意义是什么
  • Unity学习笔记之——ugui的性能优化
  • Python接口自动化中操作Excel文件的技术方法
  • [Windows] 免费电脑控制手机软件 极限投屏_正式版_3.0.1 (QtScrcpy作者开发)
  • 游戏引擎学习第131天
  • Visual Studio Code集成MarsCode AI
  • partner‘127.0.0.1:3200‘ not reached
  • 蓝桥备赛(六)- C/C++输入输出
  • Flume
  • Java 大视界 -- Java 大数据中的时间序列数据异常检测算法对比与实践(103)
  • 三次握手内部实现原理
  • ES from size聚合查询10000聚合查询,是每个分片先聚合,再统计。还是所有节点查询1万条后,再聚合
  • JAVA实战开源项目:安康旅游网站(Vue+SpringBoot) 附源码
  • Redis详解(实战 + 面试)
  • 宝塔webhooks与码云实现自动部署
  • 什么是Agentic AI?(Doubao-1.5-pro-32k 大模型开启联网回答)
  • LSTM预测模型复现笔记和问题记录