当前位置: 首页 > 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 执行错误等)。

相关文章:

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(…...

【心得】一文梳理高频面试题 HTTP 1.0/HTTP 1.1/HTTP 2.0/HTTP 3.0的区别并附加记忆方法

面试时很容易遇到的一个问题—— HTTP 1.0/HTTP 1.1/HTTP 2.0/HTTP 3.0的区别,其实这四个版本的发展实际上是一环扣一环的,是逐步完善的,本文希望帮助读者梳理清楚各个版本之间的区别,并且给出当前各个版本的应用情况,…...

Navicat连接虚拟机数据库详细教程

Navicat连接虚拟机数据库详细教程 以Windows主机 上的navicat 连接ubuntu虚拟机为例 确认虚拟机ip地址和主机ip地址 主机地址查询 cmd输入ipconfig 登录mysql 创建用户 CREATE USER newuserlocalhost IDENTIFIED BY password; CREATE USER newuser% IDENTIFIED BY passwor…...

委托者模式(掌握设计模式的核心之一)

目录 问题: 举例: 总结:核心就是利用Java中的多态来完成注入。 问题: 今天刷面经,刷到装饰者模式,又进阶的发现委托者模式,发现还是不理解,特此记录。 举例: ​老板​…...

DeepSeek-R1 论文笔记:通过强化学习提升大语言模型的推理能力

论文标题:DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 作者团队:DeepSeek-AI 发表时间:2025 前置知识 & 术语 模型蒸馏 语言模型蒸馏的目标是将大型教师模型的知识(如语义理解、上…...

实现Unity shader扭曲效果

实现思路 1、扭曲材质赋于面片 2、抓取当前一帧的图片内容 3、获取屏幕坐标 4、利用屏幕坐标对抓取的图片采样 5、再采样张扰动贴图做扭曲 Shader "Unlit/NewUnlitShader" {Properties {_DistortTex ("扰动贴图 (RGB)", 2D) "bump" {}_Di…...

七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)

七星棋牌源码 是一款运营级的棋牌产品,覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区,支持 安卓、iOS 双端,并且 全开源。这个版本是 修复优化后的二开版本,新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…...

C++STL---<limits>

C <limits> 头文件&#xff1a; <limits> 头文件是 C 标准库中用于获取各种数据类型的数值范围、精度等信息的工具。它通过模板类 std::numeric_limits 提供了对基本数据类型&#xff08;如 int、float、double 等&#xff09;的详细属性查询功能。通过 std::nume…...

一键安装Mysql部署脚本之Linux在线安装Mysql,脚本化自动化执行服务器部署(附执行脚本下载)

相关链接 一键安装Redis部署脚本之Linux在线安装Redis一键安装Mysql部署脚本之Linux在线安装Mysql一键安装JAVA部署脚本之Linux在线安装JDK一键安装Nginx部署脚本之Linux在线安装NginxNavicat最新版(17)详细安装教程Xshell客户端免费版无需注册XFtp客户端免费版无需注册 前言…...

ES、OAS、ERP、电子政务、企业信息化(高软35)

系列文章目录 ES、OAS、ERP、电子政务、企业信息化 文章目录 系列文章目录前言一、专家系统&#xff08;ES&#xff09;二、办公自动化系统&#xff08;OAS&#xff09;三、企业资源规划&#xff08;ERP&#xff09;四、典型信息系统架构模型1.政府信息化和电子政务2.企业信息…...

文生图开源模型发展史(2014-2025年)

文生图开源模型的发展历程是一段充满技术革新、社区生态繁荣与商业化竞争的多维度演进史。 一、技术萌芽期&#xff08;2014-2020年&#xff09; 核心突破 2014年&#xff1a;GAN&#xff08;生成对抗网络&#xff09;诞生&#xff0c;首次实现数据驱动式图像生成&#xff0…...

OA办公系统自动渗透测试过程

目录 一、下载环境源码 二、部署环境 三、测试 XSS漏洞 SQL注入 文件上传漏洞 一、下载环境源码 OA源码打包地址: https://download.csdn.net/download/weixin_43650289/90434502?spm=1001.2014.3001.5503 二、部署环境...

Python标准库【os】5 文件和目录操作2

文章目录 8 文件和目录操作8.7 浏览目录下的内容8.8 查看文件或目录的信息8.9 文件状态修改文件标志位文件权限文件所属用户和组其它 8.10 浏览Windows的驱动器、卷、挂载点8.11 系统配置信息 os模块提供了各种操作系统接口。包括环境变量、进程管理、进程调度、文件操作等方面…...

[代码规范]接口设计规范

一个优雅的接口要如何设计&#xff1f;有哪些设计规范可以遵循&#xff1f; 下面抛砖引玉&#xff0c;分享一些规范。 目录 1、RESTful API 设计最佳实践 2、Shneiderman 的 8 条黄金法则 3、Nielsen 的 10 条启发式规则 1、RESTful API 设计最佳实践 一共18条&#xff0c;参考…...

什么是最终一致性,它对后端系统的意义是什么

最终一致性(Eventual Consistency)是分布式系统中的一种一致性模型。与传统的强一致性模型不同,最终一致性并不要求系统在任何时刻都保持一致,而是保证在足够的时间后,所有节点的数据最终会达到一致的状态。换句话说,系统允许短时间内出现数据的不一致性,但最终会通过某…...

Unity学习笔记之——ugui的性能优化

在Unity中UI优化的核心问题就是重绘和批处理之间的平衡 一、Canvas优化要点 1.优化原因&#xff1a; &#xff08;1&#xff09;Unity为了性能优化&#xff0c;会合并Canvas下的所有元素&#xff1b; &#xff08;2&#xff09;如果把所有面板放到一个Canvas下&#xff0c;会…...

Python接口自动化中操作Excel文件的技术方法

在Python接口自动化测试中&#xff0c;操作Excel文件是一项常见且关键的技术需求。Excel作为数据存储和数据分析的重要工具&#xff0c;在自动化测试中通常用于存储测试用例、测试数据以及测试结果。通过Python操作Excel&#xff0c;可以大大提高测试的效率和灵活性。以下是一些…...

[Windows] 免费电脑控制手机软件 极限投屏_正式版_3.0.1 (QtScrcpy作者开发)

[Windows] 极限投屏_正式版 链接&#xff1a;https://pan.xunlei.com/s/VOKJf8Z1u5z-cHcTsRpSd89tA1?pwdu5ub# 新增功能(Future)&#xff1a; 支持安卓14(Supports Android 14)提高投屏成功率(Improve the success rate of mirror)加快投屏速度(Accelerate screen mirrorin…...

游戏引擎学习第131天

仓库:https://gitee.com/mrxiao_com/2d_game_3 运行游戏并识别我们的小问题 今天的工作重点是对游戏引擎进行架构优化&#xff0c;特别是针对渲染和多线程的部分。目前&#xff0c;我们的目标是让地面块在独立线程上进行渲染&#xff0c;以提高性能。在此过程中&#xff0c;我…...

Visual Studio Code集成MarsCode AI

Visual Studio Code集成MarsCode AI 1、搜索MarsCode AI 安装包 2、点击install安装即可 小编这里已经安装过了 3、登录自己的账号 点击链接&#xff0c;注册账号 https://www.marscode.cn/events/s/i5DRGqqo/ 4、登录后可以自己切换模型...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

「Java基本语法」变量的使用

变量定义 变量是程序中存储数据的容器&#xff0c;用于保存可变的数据值。在Java中&#xff0c;变量必须先声明后使用&#xff0c;声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例&#xff1a;声明与初始化 public class VariableDemo {publi…...

Selenium 查找页面元素的方式

Selenium 查找页面元素的方式 Selenium 提供了多种方法来查找网页中的元素&#xff0c;以下是主要的定位方式&#xff1a; 基本定位方式 通过ID定位 driver.find_element(By.ID, "element_id")通过Name定位 driver.find_element(By.NAME, "element_name"…...