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> 头文件: <limits> 头文件是 C 标准库中用于获取各种数据类型的数值范围、精度等信息的工具。它通过模板类 std::numeric_limits 提供了对基本数据类型(如 int、float、double 等)的详细属性查询功能。通过 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、电子政务、企业信息化 文章目录 系列文章目录前言一、专家系统(ES)二、办公自动化系统(OAS)三、企业资源规划(ERP)四、典型信息系统架构模型1.政府信息化和电子政务2.企业信息…...
文生图开源模型发展史(2014-2025年)
文生图开源模型的发展历程是一段充满技术革新、社区生态繁荣与商业化竞争的多维度演进史。 一、技术萌芽期(2014-2020年) 核心突破 2014年:GAN(生成对抗网络)诞生,首次实现数据驱动式图像生成࿰…...
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模块提供了各种操作系统接口。包括环境变量、进程管理、进程调度、文件操作等方面…...
[代码规范]接口设计规范
一个优雅的接口要如何设计?有哪些设计规范可以遵循? 下面抛砖引玉,分享一些规范。 目录 1、RESTful API 设计最佳实践 2、Shneiderman 的 8 条黄金法则 3、Nielsen 的 10 条启发式规则 1、RESTful API 设计最佳实践 一共18条,参考…...

什么是最终一致性,它对后端系统的意义是什么
最终一致性(Eventual Consistency)是分布式系统中的一种一致性模型。与传统的强一致性模型不同,最终一致性并不要求系统在任何时刻都保持一致,而是保证在足够的时间后,所有节点的数据最终会达到一致的状态。换句话说,系统允许短时间内出现数据的不一致性,但最终会通过某…...
Unity学习笔记之——ugui的性能优化
在Unity中UI优化的核心问题就是重绘和批处理之间的平衡 一、Canvas优化要点 1.优化原因: (1)Unity为了性能优化,会合并Canvas下的所有元素; (2)如果把所有面板放到一个Canvas下,会…...
Python接口自动化中操作Excel文件的技术方法
在Python接口自动化测试中,操作Excel文件是一项常见且关键的技术需求。Excel作为数据存储和数据分析的重要工具,在自动化测试中通常用于存储测试用例、测试数据以及测试结果。通过Python操作Excel,可以大大提高测试的效率和灵活性。以下是一些…...

[Windows] 免费电脑控制手机软件 极限投屏_正式版_3.0.1 (QtScrcpy作者开发)
[Windows] 极限投屏_正式版 链接:https://pan.xunlei.com/s/VOKJf8Z1u5z-cHcTsRpSd89tA1?pwdu5ub# 新增功能(Future): 支持安卓14(Supports Android 14)提高投屏成功率(Improve the success rate of mirror)加快投屏速度(Accelerate screen mirrorin…...

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

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

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...