gorm 结构体方式查询更新等操作忽略零值这个事儿影响不大吗?

2021-08-25 20:41:20 +08:00
 chaleaoch
譬如 bool 值 这种 false 是很常见的一种操作.

在实际的开发中,如何处理这种情况. 都定义成指针? 还是 都用 map 更新?

最佳实践是什么?

谢谢大佬.
2923 次点击
所在节点    Go 编程语言
17 条回复
han3sui
2021-08-25 20:50:36 +08:00
应该用指针吧
RTSmile
2021-08-25 21:10:49 +08:00
注意 当通过 struct 更新时,GORM 只会更新非零字段。 如果您想确保指定字段被更新,你应该使用 Select 更新选定字段,或使用 map 来完成更新操作

官网不是给了吗
yrj
2021-08-25 21:11:11 +08:00
可以用 select 指定吧
pluvet
2021-08-25 21:25:16 +08:00
这个确实很难受。目前是禁止用 Updates,都用 Save 、Select 等。
chaleaoch
2021-08-25 21:26:26 +08:00
@RTSmile 明白. 谢谢.
CEBBCAT
2021-08-25 23:17:24 +08:00
没太明白,是数据库没有设计默认 DEFAULT '0'吗?还是写 DAO 的时候没有 UpdateColumn(map)?

我遇到的场景都还是比较适合使用 map 指定更新字段的,不知道楼主的场景是怎样的。不过建议设置良好的 logger,这样可以对 gorm 的行为心里有底
freakxx
2021-08-25 23:19:19 +08:00
开始写 go 这边的 crud 确实有这个难受的问题;

后面把结构换为指针,
塞进去的时候,判断值是否为 nil,
nil 的话就略过。
chaleaoch
2021-08-25 23:37:47 +08:00
@CEBBCAT
没太明白,是数据库没有设计默认 DEFAULT '0'吗?
-- 就是 update 一个 bool 从 True --> false 但是因为 false 是零值所以 update 失败.

我遇到的场景都还是比较适合使用 map 指定更新字段的,不知道楼主的场景是怎样的。
-- 我是 go/gorm 新手还没开始敲 go 代码. 就是看文档的时候遇到了这个说明所以很奇怪 真正的实际开发过程中是如何处理这个问题的. 我在脑子里空想 无论是指针 还是 values scan 都听麻烦的.
map 合适吗? 我不知道. 因为目前我看到的有限的 go 代码用结构体用的都挺多的.

所以上来问问有经验的大佬们.
chaleaoch
2021-08-25 23:39:02 +08:00
@freakxx 那岂不是一堆指针 我看到有限的开源代码里面的指针并不很多.
ihipop
2021-08-25 23:43:02 +08:00
@pluvet save 不用 select 会整个 struct 全部写库,你读出的数据是有可能滞后的,导致库内数据被覆盖
freakxx
2021-08-25 23:48:47 +08:00
@chaleaoch #9

是滴,代码会有点脏,后续可能需要再重新统一下

但如果不这么搞,确实没好办法,挺恶心的。。。
你根本不知道你从外面塞进来的 0 是真的 0 还是默认的 0
pluvet
2021-08-25 23:52:51 +08:00
@ihipop 倒是可以事务+行锁,不过就更麻烦了。你有没有好办法?
ooh
2021-08-26 00:05:13 +08:00
hpeng
2021-08-26 00:21:28 +08:00
go 的破问题,感觉除了指针没什么更好的解法了
CEBBCAT
2021-08-26 00:26:16 +08:00
@chaleaoch #8 哈哈,我更愿意称之为失败的 update,而不是 update 失败。零值问题手动使用 map 指定要更新的字段就好了,我想麻烦不是很多。如果你不想用 map 的方式,楼上说的 Select 也可以考虑一下。他们其实核心作用都是明明白白地告诉 ORM,你要更新的字段是哪些

结构体当然很常用呀,但我想 gorm 这边只好依着它来了。其实我之前都是手写 SQL 的,没错,手动 Scan Field 。我觉得即使是手写 SQL 工作量也不会多出来多少吧,所以也许你可以试用一下 DB.Exec() ?哈哈,祝好运
ihipop
2021-08-26 07:26:00 +08:00
@pluvet 我想表达的和事物锁没有关系,我的意思是说 save 会保存整个 struct 的所有值,如果你新建,所有 0 值字段都会写入,如果你更新,所有先前读出的映射到 struct 的字段包含 struct 自带的 0 值哪怕没有修改过,都会被回写,而这些年当前业务没修改的字段在数据库可能已经被其它业务改过,你光用 save 就会导致这些业务数据回退,所以必须 save 配合 select 指定你修改的业务字段,这么麻烦还不如用 updates+map 。
labulaka521
2021-08-26 09:50:14 +08:00
用 save 前端会返回这个结构体的时候数据,偶尔会用 update map 来更新

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/798006

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX