gorm 更新数据时,0值会被忽略
原文: https://www.tizi365.com/archives/22.html
--------------------------------------------------------
一、前言
为方便描述教程例子,这里给出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"))
gorm 更新数据时,0值会被忽略的更多相关文章
- FreeSql (十二)更新数据时指定列
var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + "Initia ...
- FreeSql (十三)更新数据时忽略列
var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + "Initia ...
- mongodb 更新数据时int32变为double的解决办法 & 教程
https://www.runoob.com/mongodb/mongodb-mongodump-mongorestore.html mongodb 更新数据时int32变为double的解决办法 ...
- mongoose 更新数据时不验证数据(忽略设定的集合规则)的问题
问题: mongoose 更新数据时不验证数据(忽略设定的集合规则)的问题 参考: http://www.mongoosejs.net/docs/api.html#updateone_updateOn ...
- 在Oracle中更新数据时,抛出:ORA-01008: not all variables bound
在Oracle中更新数据时,抛出了一个 :ORA-01008 not all variables bound, 我的理解是不是所有的变量/参数都有边界,不懂: 后来知道了,原来是“不是所有变量/参数都 ...
- SQL中使用UPDATE更新数据时一定要记得WHERE子句
我们在使用 SQL 中的 UPDATE 更新数据时,一般都不会更新表中的左右数据,所以我们更新的数据的 SQL 语句中会带有 WHERE 子句,如果没有WHERE子句,就回更新表中所有的数据,在 my ...
- ORACLE更新数据时如果有就更新没有就插入
SQL写法: begin update table_name set salary = 10000 where emp_id = 5; if sql%notfound then insert into ...
- MySQL更新数据时,日志(redo log、binlog)执行流程
1:背景 项目需要做Es和数据库的同步,而手动在代码中进行数据同步又是Es的一些不必要的数据同步操作和业务逻辑耦合,所以使用的了读取mysql的binlog日志的方式进行同步Es的数据. 问题1:根据 ...
- 使用xadmin更新数据时,报错expected string or bytes-like object
expected string or bytes-like object 期望的字符串或类似字节的对象,一般为数据类型不匹配造成 本人在实际项目里发现的问题是: 数据库里的字段类型与django里mo ...
随机推荐
- leetcode1186 Maximum Subarray Sum with One Deletion
思路: 最大子段和的变体,前后两个方向分别扫一遍即可. 实现: class Solution { public: int maximumSum(vector<int>& arr) ...
- 【VS开发】Windows平台下Makefile学习笔记
作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译平台的问题(发现一些开源代码已经在使用VS2010开 ...
- in-place数据交换
实现in-place的数据交换 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 经典的排序问题 问题描述 一个数组中包含两个已经排好序的子数组,设计一个in- ...
- DSP6455的EMIFA口
DSP6455的EMIFA口 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 支持两种不同的接口模式: 异步接口:标准的SRAM,ROM接口 同步接口:SBS ...
- python线程定时器Timer(32)
相对前面几篇python线程内容而言,本片内容相对比较简单,定时器 – 顾名思义,必然用于定时任务. 一.线程定时器Timer原理 原理比较简单,指定时间间隔后启动线程!适用场景:完成定时任务,例如: ...
- React native 禁止手势触摸 pointerEvents
碰到一个需求是做个轮播图带自动播放的,UED那边给轮播的底部加了阴影渐变,如下红色区域. 这样会导致一个问题,手触摸在红色区域会被这层View挡住,导致不能手动滑动切换. 原先采取过的方法是在对应的触 ...
- kibana发音 logstash发音 ElasticSearch发音 音标 翻译
kibana [kɪbana] 剋吧那 kei ba na == 扩展 logstash [lɔɡ] [stæ:ʃ] 楼个四die吃 == ElasticSearch [ɪˈlæstɪk] [sɜːt ...
- Java语言资源国际化步骤
语言资源国际化步骤: 1. 定义资源文件(如:language),需要使用命令native2ascii命令进行转码:(native2ascii是jdk中的转码工具,在jdk的bin目录下) 2 ...
- python--接口自动化测试(接口状态)
本节开始,开始介绍python的接口自动化测试,首先需要搭建python开发环境,到https://www.python.org/下载python 版本直接安装就以了,建议 下载python2.7.1 ...
- 使用Duilib开发Windows软件(5)——使用VLC做视频播放
需求:调用PC上的摄像头拍照. 实现思路:接入视频流,截屏获取照片. 早期的vlc安装包(Windows)是附带sdk包的,现在的安装后已经没有了,原因如下: VLC SDK下载连接:https:// ...