当前位置:网站首页>Gorm 更新零值问题
Gorm 更新零值问题
2022-07-30 06:38:00 【Ch3n】
一、前言
为方便描述教程例子,这里给出mysql表结构定义和golang结构体定义。
下面是教程用到的foods
表结构定义:
CREATE TABLE `foods` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
`title` varchar(100) NOT NULL COMMENT '商品名',
`price` float DEFAULT '0' COMMENT '商品价格',
`stock` int(11) DEFAULT '0' COMMENT '商品库存',
`type` int(11) DEFAULT '0' COMMENT '商品类型',
`create_time` datetime NOT NULL COMMENT '商品创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
下面是foods表对应的golang结构体类型
//商品
type Food struct {
Id int
Title string
Price float32
Stock int
Type int
//mysql datetime, date类型字段,可以和golang time.Time类型绑定, 详细说明请参考:gorm连接数据库章节。
CreateTime time.Time
}
//为Food绑定表名
func (v Food) TableName() string {
return "foods"
}
二、gorm更新记录常用方法
1. Save
用于保存模型变量的值。
提示: 相当于根据主键id,更新所有模型字段值。
food := Food{
}
//先查询一条记录, 保存在模型变量food
//等价于: SELECT * FROM `foods` WHERE (id = '2') LIMIT 1
db.Where("id = ?", 2).Take(&food)
//修改food模型的值
food.Price = 100
//等价于: UPDATE `foods` SET `title` = '可乐', `type` = '0', `price` = '100', `stock` = '26', `create_time` = '2018-11-06 11:12:04' WHERE `foods`.`id` = '2'
db.Save(&food)
2. Update
更新单个字段值
//例子1:
//更新food模型对应的表记录
//等价于: UPDATE `foods` SET `price` = '25' WHERE `foods`.`id` = '2'
db.Model(&food).Update("price", 25)
//通过food模型的主键id的值作为where条件,更新price字段值。
//例子2:
//上面的例子只是更新一条记录,如果我们要更全部记录怎么办?
//等价于: UPDATE `foods` SET `price` = '25'
db.Model(Food{
}).Update("price", 25)
//注意这里的Model参数,使用的是Food{},新生成一个空白的模型变量,没有绑定任何记录。
//因为Food{}的id为空,gorm库就不会以id作为条件,where语句就是空的
//例子3:
//根据自定义条件更新记录,而不是根据主键id
//等价于: UPDATE `foods` SET `price` = '25' WHERE (create_time > '2018-11-06 20:00:00')
db.Model(Food{
}).Where("create_time > ?", "2018-11-06 20:00:00").Update("price", 25)
3. Updates
更新多个字段值
//例子1:
//通过结构体变量设置更新字段
updataFood := Food{
Price:120,
Title:"柠檬雪碧",
}
//根据food模型更新数据库记录
//等价于: UPDATE `foods` SET `price` = '120', `title` = '柠檬雪碧' WHERE `foods`.`id` = '2'
//Updates会忽略掉updataFood结构体变量的零值字段, 所以生成的sql语句只有price和title字段。
db.Model(&food).Updates(&updataFood)
//例子2:
//根据自定义条件更新记录,而不是根据模型id
updataFood := Food{
Stock:120,
Title:"柠檬雪碧",
}
//设置Where条件,Model参数绑定一个空的模型变量
//等价于: UPDATE `foods` SET `stock` = '120', `title` = '柠檬雪碧' WHERE (price > '10')
db.Model(Food{
}).Where("price > ?", 10).Updates(&updataFood)
//例子3:
//如果想更新所有字段值,包括零值,就是不想忽略掉空值字段怎么办?
//使用map类型,替代上面的结构体变量
//定义map类型,key为字符串,value为interface{}类型,方便保存任意值
data := make(map[string]interface{
})
data["stock"] = 0 //零值字段
data["price"] = 35
//等价于: UPDATE `foods` SET `price` = '35', `stock` = '0' WHERE (id = '2')
db.Model(Food{
}).Where("id = ?", 2).Updates(data)
提示: 通过结构体变量更新字段值, gorm库会忽略零值字段。就是字段值等于0, nil, “”, false这些值会被忽略掉,不会更新。如果想更新零值,可以使用map类型替代结构体。
4. 更新表达式
UPDATE foods SET stock = stock + 1 WHERE id = '2'
这样的带计算表达式的更新语句gorm怎么写?
gorm提供了Expr函数用于设置表达式
//等价于: UPDATE `foods` SET `stock` = stock + 1 WHERE `foods`.`id` = '2'
db.Model(&food).Update("stock", gorm.Expr("stock + 1"))
二、 使用struct更新仅适用于非零值
user:=User{
Name:"",
Age:0,
Actived:false,
}
db.Model(&user).Updates(user)
//此时不会更新这些零值,如需更新零值使用map
userMap:=map[string]interface{
}{
"name":"",
"age":0,
"actived":0,
}
db.Model(&user).Updates(userMap)
边栏推荐
- Link with Bracket Sequence II(杭电多校赛)
- RT-Thread-GD32的SPI在切换同一总线不同挂载设备时会出现切换后乱发送数据的问题
- DP5340国产替代CM5340立体声音频A/D转换器芯片
- 树状数组的基本用法
- Develop common tool software
- 一段神奇的没有主方法的代码
- 【防作弊】Unity防本地调时间作弊
- Go combines Gin to export Mysql data to Excel table
- Selected as one of the "Top Ten Hard Core Technologies", explaining the technical points of Trusted Confidential Computing (TECC) in detail
- 【COCI 2020/2021 Round #2 D】Magneti (DP)
猜你喜欢
随机推荐
【雷达目标检测】恒定阈值法和恒虚警(CFAR)法及代码实现
Go combines Gin to export Mysql data to Excel table
进制转换。。。
【COCI 2020/2021 Round #2 D】Magneti(DP)
C# 使用RestSharp 实现Get,Post 请求(2)
Limit injection record of mysql injection in No. 5 dark area shooting range
go : 使用gorm创建数据库记录
go : 使用 grom 删除数据库数据
Derivative Operations on Vectors and Derivative Operations on Vector Cross and Dot Products
物联网网关该怎么选
C# uses RestSharp to implement Get, Post requests (2)
通过位运算进行两个变量值的交换功能
golang : Zap日志整合
mysql高阶语句(一)
使用navicat连接mysql数据库时常报的错误:2003、1698、1251
01 多线程与高并发 - 基础概念
【BERT-多标签文本分类实战】之二——BERT的地位与名词术语解释
Go 使用 freecache 缓存
go : go-redis list操作
保存在 redis中的token 如何续期?