Gorm -- 添加记录
创始人
2024-05-27 13:45:11
0

文章目录

    • 添加单条记录
      • 直接添加模型对象
      • 赋予默认值方法一: 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('测试', '拼接')

相关内容

热门资讯

武汉摩尔影城安卓系统APP,便... 你有没有想过,一部手机就能带你走进电影的世界,享受大屏幕带来的震撼?今天,就让我带你详细了解武汉摩尔...
联想刷安卓p系统,畅享智能新体... 你有没有发现,最近联想的安卓P系统刷机热潮可是席卷了整个互联网圈呢!这不,我就迫不及待地来和你聊聊这...
mac从安卓系统改成双系统,双... 你有没有想过,你的Mac电脑从安卓系统改成双系统后,生活会有哪些翻天覆地的变化呢?想象一边是流畅的苹...
kindke安卓系统激活码,激... 亲爱的读者,你是否在寻找一款能够让你手机焕然一新的操作系统?如果你是安卓用户,那么今天我要给你带来一...
萤石云监控安卓系统,安卓系统下... 你有没有想过,家里的安全可以随时随地掌握在手中?现在,有了萤石云监控安卓系统,这不再是梦想啦!想象无...
手机安卓系统会不会爆炸,系统升... 手机安卓系统会不会爆炸——一场关于安全的探讨在当今这个数字化的世界里,手机已经成为我们生活中不可或缺...
安卓系统双清详图解,恢复出厂设... 你有没有遇到过手机卡顿、运行缓慢的问题?别急,今天就来给你详细解析一下安卓系统的“双清”操作,让你的...
召唤抽奖系统安卓直装,轻松体验... 你知道吗?现在市面上有一种特别火的玩意儿,那就是召唤抽奖系统安卓直装。是不是听起来就让人心动不已?没...
系统工具箱安卓2.3,深度解析... 你有没有发现,手机里的那些小工具,有时候就像是个神奇的百宝箱呢?今天,就让我带你一探究竟,看看安卓2...
华硕平板安卓刷机系统,解锁性能... 亲爱的数码爱好者们,你是否曾为你的华硕平板安卓系统感到厌倦,想要给它来一次焕然一新的体验呢?那就跟着...
鸿蒙系统与安卓怎么区别,差异解... 你有没有发现,最近手机圈子里有个大热门,那就是鸿蒙系统和安卓系统的区别。这两位“系统大侠”各有各的绝...
红帽系统怎么刷回安卓,红帽系统... 你是不是也和我一样,对红帽系统刷回安卓充满了好奇?别急,今天就来给你详细揭秘这个过程,让你轻松上手,...
ios安卓联想三系统,全面解析... 你有没有发现,现在的手机市场真是热闹非凡呢!各种操作系统轮番登场,让人眼花缭乱。今天,就让我带你来聊...
安卓调用系统相机并存盘,And... 你有没有想过,手机里的照片和视频,是怎么被我们随手拍下,又神奇地存到手机里的呢?今天,就让我带你一探...
安卓4.0原生系统下,引领智能... 你有没有发现,安卓4.0原生系统下,手机的使用体验简直就像打开了新世界的大门?今天,就让我带你一起探...
安卓c13系统,创新功能与性能... 你知道吗?最近安卓系统又来了一次大更新,那就是安卓C13系统。这可不是一个小打小闹的更新,而是带来了...
鸿蒙3.0脱离安卓系统,开启全... 你知道吗?最近科技圈可是炸开了锅,因为华为的新操作系统鸿蒙3.0横空出世,竟然宣布要脱离安卓系统,这...
安卓怎么应对苹果系统,安卓系统... 你知道吗?在智能手机的世界里,安卓和苹果就像是一对相爱相杀的恋人。安卓系统,这位多才多艺的“大众情人...
安卓系统如何开橱窗教程,安卓系... 你有没有想过,你的安卓手机里也能开个橱窗,展示那些你心爱的宝贝?没错,就是那种可以随时翻看、随时分享...
安卓系统软件APK,深入探究安... 你有没有发现,手机里的那些好玩的应用,其实都是靠一个小小的文件来“住”进去的?没错,就是安卓系统里的...