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

Gorm -- 添加记录

文章目录

    • 添加单条记录
      • 直接添加模型对象
      • 赋予默认值方法一: gorm 标签
      • 赋予默认值方法二: 设置钩子方法(Hooks)
      • 指定字段插入
      • 插入时忽略某些字段
      • 插入时禁止使用钩子方法
    • 添加多条记录
      • 通过对象列表插入
      • 通过字典列表插入
      • 在字典中使用SQL内置函数
    • 关联插入
    • 取消关联插入
      • 取消指定关联插入
      • 取消所有关联插入
    • 冲突
      • 忽略冲突
      • 出现冲突修改行记录
        • 出现冲突时,修改字段为新的值
        • 出现冲突时,修改指定字段为新的值
        • 出现冲突时,修改指定字段内容
        • 使用内置函数

模型定义以及Gorm初始化请参考上一篇文章 https://mingvvv.blog.csdn.net/article/details/129026914

首先初始化连接池

db := cus_orm.MysqlConnection()

添加单条记录

直接添加模型对象

使用 Debug() 可以打印出 SQL 语句,开发时使用便于观察

user := &model.User{Name: "姓名",
}
// 添加一条
if err := db.Debug().Create(user).Error; err != nil {fmt.Println(err)return
}
-------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 15:24:56','2023-03-01 15:24:56')

这里的对象中我们只给 Name 赋值,但是在实际执行的 SQL 中其他字段也有值,原因如下:

赋予默认值方法一: gorm 标签

在这里插入图片描述

赋予默认值方法二: 设置钩子方法(Hooks)

为结构体添加以下方法:
在这里插入图片描述
在模型对象创建的时候会依次调用这四个方法,执行循序为
BeforeSave => BeforeCreate => AfterCreate => AfterSave
因此我们可以在这些方法里面对对象做一些操作,如下,对CreateTime、UpdateTime、 UserDesc 做了简单的赋值

... ...
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {u.CreateTime = time.Unix(time.Now().Unix(), 0) //初始化创建时间u.UpdateTime = time.Unix(time.Now().Unix(), 0) //初始化修改时间u.UserDesc = "这是一条默认描述"fmt.Println("BeforeCreate -- Auto Setting")return
}
... ...

指定字段插入

db.Debug().Select("Name").Create(&user)
db.Debug().Select("Name","UserDesc").Create(&user)
---------------------------
INSERT INTO `user` (`name`) VALUES ('姓名')
INSERT INTO `user` (`name`,`user_desc`) VALUES ('姓名','这是一条默认描述')

插入时忽略某些字段

忽略 UpdateTime

db.Debug().Omit("UpdateTime").Create(&user)
----------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`id`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 15:50:59',539)

插入时禁止使用钩子方法

有的时候我们在保存时可能不需要狗子方法帮我们预处理数据,所以我们要禁用钩子方法
使用 Session(&gorm.Session{SkipHooks: true}),会发现我们上面在钩子方法没有执行

import "gorm.io/gorm"
db.Debug().Omit("UpdateTime").Session(&gorm.Session{SkipHooks: true}).Create(&user)
-------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'',NULL,'0000-00-00 00:00:00','0000-00-00 00:00:00')

添加多条记录

通过对象列表插入

CreateInBatches(&users, 100) 100表示每次插入的最大行数量。列表内的对象数量大于这个值时会分批次插入,每批次最大 100 行

users := []model.User{
{Name: "测试goper111",},{Name: "测试goper222",},{Name: "测试goper333",},
}
db.Debug().CreateInBatches(&users, 100)
--------------------------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES 
('测试goper111','',18,'这是一条默认描述',NULL,'2023-03-01 16:04:18','2023-03-01 16:04:18'),
('测试goper222','',18,'这是一条默认描述',NULL,'2023-03-01 16:04:18','2023-03-01 16:04:18'),
('测试goper333','',18,'这是一条默认描述',NULL,'2023-03-01 16:04:18','2023-03-01 16:04:18')

通过字典列表插入

db.Model(&model.User{}).Debug().Create([]map[string]interface{}{{"Name": "姓名1", "Age": 18},{"Name": "姓名2", "Age": 20},
})
-------------------
INSERT INTO `user` (`age`,`name`) VALUES 
(18,'姓名1'),
(20,'姓名2')

在字典中使用SQL内置函数

使用 clause.Expr{SQL: “内置函数”, Vars: []interface{}{参数对象}}

import "gorm.io/gorm/clause"db.Model(&model.User{}).Debug().Create([]map[string]interface{}{{"Name": clause.Expr{SQL: "Concat(?,?)", Vars: []interface{}{"姓名", "拼接"}}, "Age": 18},
})
----------------------------------------
INSERT INTO `user` (`age`,`name`) VALUES (18,Concat('姓名','拼接'))

还有一种方法也可以使用内置函数,但是需要提前自定义数据类型,比较繁琐。
实现过程可参考以下地址

https://gorm.io/docs/data_types.html#GormValuerInterface

关联插入

在结构体 User 中,我们最后两个字段关联了其他两个表。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果我们要插入的对象中,这两个元素不是空值,那么这两个结构体对应的表也会插入数据。
需要注意的是:
上图红框中我们制定了外键关系,即这两个表的 user_id 就是 user 表的外键,所以在插入时,这两个表的 user_id 会自动赋值为 user 表的 id

user2 := &model.User{Name: "姓名",UserRole: model.UserRole{RoleId: 1,},UserExtend: model.UserExtend{Gender: 1,},
}
db.Debug().Create(&user2)
--------------------------------------------
INSERT INTO `user_role` (`user_id`,`role_id`) VALUES (546,1) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
INSERT INTO `user_extend` (`user_id`,`gender`) VALUES (546,1) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 16:22:25','2023-03-01 16:22:25')

取消关联插入

取消指定关联插入

以下取消了 user_role 表的关联插入

user2 := &model.User{Name: "姓名",UserRole: model.UserRole{RoleId: 1,},UserExtend: model.UserExtend{Gender: 1,},
}
db.Debug().Omit("UserRole").Create(&user2)
-----------------------------------------
INSERT INTO `user_extend` (`user_id`,`gender`) VALUES (547,1) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 16:29:09','2023-03-01 16:29:09')

取消所有关联插入

import "gorm.io/gorm/clause"
user2 := &model.User{Name: "姓名",UserRole: model.UserRole{RoleId: 1,},UserExtend: model.UserExtend{Gender: 1,},
}
db.Debug().Omit(clause.Associations).Create(&user2)
-----------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 16:29:09','2023-03-01 16:29:09')

冲突

我们在创建表的时候会创建一些唯一索引,这样的索引对应的列在表内是不允许存在重复数据的。
当我们插入了重复数据后,插入会报错。针对这种情况,我们可以忽略这些冲突或者将插入操作转变为修改操作。

忽略冲突

当出现冲突时,将id修改为id,实质上相当于什么也没做

user := &model.User{Id:        521,Name:      "姓名",JsonField: map[string]string{"test": "test"},
}
db.Debug().Clauses(clause.OnConflict{DoNothing: true}).Create(&user)
--------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`) 
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 16:55:24','2023-03-01 16:55:24',521) 
ON DUPLICATE KEY UPDATE `id`=`id`

出现冲突修改行记录

出现冲突时,修改字段为新的值

user := &model.User{Id:        521,Name:      "姓名",JsonField: map[string]string{"test": "test"},
}
db.Debug().Clauses(clause.OnConflict{UpdateAll: true}).Create(&user)
---------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`) 
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 17:20:13','2023-03-01 17:20:13',521) 
ON DUPLICATE KEY UPDATE `name`=VALUES(`name`),`infant_name`=VALUES(`infant_name`),`age`=VALUES(`age`),`user_desc`=VALUES(`user_desc`),`json_field`=VALUES(`json_field`),`create_time`=VALUES(`create_time`),`update_time`=VALUES(`update_time`)

出现冲突时,修改指定字段为新的值

db.Debug().Clauses(clause.OnConflict{DoUpdates: clause.AssignmentColumns([]string{"json_field", "name"}),
}).Create(&user)
---------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`) 
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 17:17:35','2023-03-01 17:17:35',521) 
ON DUPLICATE KEY UPDATE `user_desc`=VALUES(`user_desc`),`name`=VALUES(`name`)

出现冲突时,修改指定字段内容

db.Debug().Clauses(clause.OnConflict{DoUpdates: clause.Assignments(map[string]interface{}{"user_desc": "冲突后做了修改"}),
}).Create(&user)
--------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`) 
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 16:51:45','2023-03-01 16:51:45',521) 
ON DUPLICATE KEY UPDATE `user_desc`='冲突后做了修改'

使用内置函数

db.Debug().Clauses(clause.OnConflict{DoUpdates: clause.Assignments(map[string]interface{}{"user_desc": gorm.Expr("Concat('测试', '拼接')")}),
}).Create(&user)
--------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`) 
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 17:15:17','2023-03-01 17:15:17',521) 
ON DUPLICATE KEY UPDATE `user_desc`=Concat('测试', '拼接')

相关文章:

Gorm -- 添加记录

文章目录添加单条记录直接添加模型对象赋予默认值方法一: gorm 标签赋予默认值方法二: 设置钩子方法(Hooks)指定字段插入插入时忽略某些字段插入时禁止使用钩子方法添加多条记录通过对象列表插入通过字典列表插入在字典中使用SQL内…...

go提高升阶(四) I/O流学习

I/O 官网课程 购买课程找博主推荐 文章目录I/O文件信息创建文件、目录IO读IO写(权限)文件复制Seeker接口断点续传遍历文件夹bufio电脑中一切,都是以 二进制流的形式存在的。jpg:010100000010010101001010101010010101010 编码格式,还原为一个…...

【代码随想录训练营】【Day28】第七章|回溯算法|93.复原IP地址|78.子集|90.子集II

复原IP地址 题目详细:LeetCode.93 这道题与上一道练习题分割回文字符串十分详细,一样是涉及到分割字符串、判断字符串、递归与回溯的问题,所以这道题要解决的难点在于: 如何分割IP地址字符串如何判断分割的IP地址是否合法递归的…...

Get请求和Post请求区别

前后端交互请求数据的方式有很多种。 例如:Get Post Put Patch Delete Copy 等等很多请求方式 但是用的最多的就是Get和Post Get请求方式 1. get多用于从服务器请求获取数据 2.get传送的数据量较小,不能大于2KB 3.get安全性非常低 Post请求方式 1.…...

static关键字

static的基本基本用法可以分为下面几种: (1)static修饰全局变量 (2) 修饰局部变量 (3)修饰普通函数 (4)修饰类的成员变量 一、static修饰全局变量 当同时编译多个文件时…...

A Comprehensive Tool for Modeling CMOS Image-Sensor-Noise Performance论文总结及翻译

A Comprehensive Tool for Modeling CMOS Image-Sensor-Noise Performance Author: Ryan D. Gow Link: https://ieeexplore.ieee.org/document/4215175/metrics#metrics Select: ⭐️⭐️⭐️⭐️ Type: Academic Journal 备注: CMOS图像传感器噪声性能建模的综合工具 总结 …...

嘀嗒出行再闯IPO:千军万马我无懈

羽扇纶巾笑谈间,千军万马我无懈。 在激烈竞争中再度冲刺港交所IPO的嘀嗒出行,闪露出一丝歌词里的气魄。交通运输部下属网约车监管信息交互系统的数据显示,截至2023年1月31日,全国共有300家网约车平台公司取得网约车平台经营许可。…...

MATLAB算法实战应用案例精讲-【优化算法】增强型鲸鱼优化算法(EWOA)(附matlab代码实现)

前言 增强型鲸鱼优化算法(Enhanced Whale Optimization Algorithm,EWOA)是Mohammad H. Nadimi-Shahraki等人于2022年提出的一种改进算法。由于标准的鲸鱼优化算法及其它的改进算法都存在种群多样性低和搜索策略差的问题,因此引入有效的策略来缓解鲸鱼优化算法的这些核心缺点…...

登录Oracle数据库遇到ORA-01017密码错误的解决办法

文章目录症状分析解决办法欢迎加下方我的微信👇,拉你入学习群我们在登录Oracle数据库时可能会遇到ORA-01017错误,这里分析原因并提供解决办法。点击试看博主的专著《MySQL 8.0运维与优化》(清华大学出版社) 症状 图像…...

10个黑客基础教程!简单有效

如果你的电脑运行缓慢,请使用下面介绍的方法来帮助加速、优化和提高电脑的性能。 1.关闭启动时自动运行的应用程序 计算机上安装的许多应用程序都可以将自己配置为在启动期间自动启动并继续在后台运行,但是,如果不是每天都使用这些应用程序…...

JPA之实体之间的关系

JPA之实体之间的关系 10.1.1实体类创建 注解的应用 Table,Entity IdGeneratedValue指定主键,Column P174 实体类编写规范 Table(name "t_user") Entity(name "User") public class User implements Serializable {IdGeneratedVa…...

如何在 C++ 中调用 python 解析器来执行 python 代码(三)?

本文在 C 中调用 multi.py 脚本,并向它传入参数并执行,然后获得返回值并在 C 中打印结果。 目录 如何在 C 中调用 python 解析器来执行 python 代码(一)?如何在 C 中调用 python 解析器来执行 python 代码&#xff0…...

【Linux】gcc/g++/gdb的使用

🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️小林爱敲代码       🛰️社区 : 进步学堂       🛰️欢迎关注:👍点赞🙌收…...

浅浅谈一谈B树和B+树

目录: 🚀1.B树 🚀2.B树 索引背后的数据结构是啥呢,是B树,是为了数据库索引设计的,我们可以先了解B树,再说B树 1.什么是B树 B树也叫B-树,这里的-不读减,是一个符号 我们已经学过了二叉搜素树,B树其实就是N叉搜素树,二叉搜索树只能在每一个结点放一个…...

Keil新建一个国民32位MCU工程

1.打开Keil软件,点击Project→New uVision→Project 2.将工程保存到自己的工程文件夹,并给项目命名,点击保存 3.选择自己需要开发的芯片,点击OK 4.点击OK 5.出现上图所示,工程已经建好了,点击配置工程。 6.…...

webpack.config.js与package.json文件的配置

path要使用绝对路径,通过每次复制文件位置非常麻烦且容易导致问题 使用node中的 写个包名跟入口名称,其他全部回车 此步完成后,自动生成一个package.json包 licence指的是开源,一般不写 安装文件夹需要的依赖 dirname是node自带…...

超详细Eclipse配置JDK

在此附上Eclipse安装教程 超详细Eclipse安装教程 在此附上JDK1.8安装配置教程 超详细JDK1.8安装与配置 ①打开Eclipse–>点击Window–>点击Preferences ②找到Java–>找到Installed JREs–>点击Add… ③选中Standard VM–>之后点击Next ④点击Directory找…...

成功解决numpy.linalg.LinAlgError: SVD did not converge in Linear Least Squares

成功解决numpy.linalg.LinAlgError: SVD did not converge in Linear Least Squares 目录 解决问题 解决思路 解决方法—四大原因分析 T1、数据本身问题的解决方法...

Allegro如何设置铜皮避让的优先级操作指导

Allegro如何设置铜皮避让的优先级操作指导 在用Allegro进行PCB设计的时候,时常需要使用动态铜皮进行设计,当两块动态铜皮存在交集的时候,避让就会存在一个优先级,如下图 上方的铜皮避让调了下方的铜皮,上方的铜皮被避让了 如何调整让下方的铜皮避让上方的铜皮,如下图 具…...

(Trie Tree)字典树

(Trie Tree)字典树 场景:在n个字符串中查找某个字符串。 暴力匹配,时间复杂度为O(nm),m为字符串平均长度,效率过低。 字典查找单词"fly",首先查找’f’,然后…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

centos 7 部署awstats 网站访问检测

一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...

深入理解 React 样式方案

React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...