V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
chaleaoch

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

  •  
  •   chaleaoch · Aug 25, 2021 · 3598 views
    This topic created in 1712 days ago, the information mentioned may be changed or developed.
    譬如 bool 值 这种 false 是很常见的一种操作.

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

    最佳实践是什么?

    谢谢大佬.
    Supplement 1  ·  Aug 26, 2021
    然后我想问一下 针对 查询操作, 结构体 零值忽略问题 如何处理?
    我本地试了一下, select 针对零值 update 有效, 查询无效啊.


    谢谢谢谢.
    han3sui
        1
    han3sui  
       Aug 25, 2021 via iPhone   ❤️ 1
    应该用指针吧
    RTSmile
        2
    RTSmile  
       Aug 25, 2021
    注意 当通过 struct 更新时,GORM 只会更新非零字段。 如果您想确保指定字段被更新,你应该使用 Select 更新选定字段,或使用 map 来完成更新操作

    官网不是给了吗
    yrj
        3
    yrj  
       Aug 25, 2021 via iPad   ❤️ 1
    可以用 select 指定吧
    pluvet
        4
    pluvet  
       Aug 25, 2021   ❤️ 1
    这个确实很难受。目前是禁止用 Updates,都用 Save 、Select 等。
    chaleaoch
        5
    chaleaoch  
    OP
       Aug 25, 2021
    @RTSmile 明白. 谢谢.
    CEBBCAT
        6
    CEBBCAT  
       Aug 25, 2021
    没太明白,是数据库没有设计默认 DEFAULT '0'吗?还是写 DAO 的时候没有 UpdateColumn(map)?

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

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

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

    所以上来问问有经验的大佬们.
    chaleaoch
        9
    chaleaoch  
    OP
       Aug 25, 2021
    @freakxx 那岂不是一堆指针 我看到有限的开源代码里面的指针并不很多.
    ihipop
        10
    ihipop  
       Aug 25, 2021 via Android
    @pluvet save 不用 select 会整个 struct 全部写库,你读出的数据是有可能滞后的,导致库内数据被覆盖
    metamask
        11
    metamask  
       Aug 25, 2021
    @chaleaoch #9

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

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

    结构体当然很常用呀,但我想 gorm 这边只好依着它来了。其实我之前都是手写 SQL 的,没错,手动 Scan Field 。我觉得即使是手写 SQL 工作量也不会多出来多少吧,所以也许你可以试用一下 DB.Exec() ?哈哈,祝好运
    ihipop
        16
    ihipop  
       Aug 26, 2021 via Android   ❤️ 1
    @pluvet 我想表达的和事物锁没有关系,我的意思是说 save 会保存整个 struct 的所有值,如果你新建,所有 0 值字段都会写入,如果你更新,所有先前读出的映射到 struct 的字段包含 struct 自带的 0 值哪怕没有修改过,都会被回写,而这些年当前业务没修改的字段在数据库可能已经被其它业务改过,你光用 save 就会导致这些业务数据回退,所以必须 save 配合 select 指定你修改的业务字段,这么麻烦还不如用 updates+map 。
    labulaka521
        17
    labulaka521  
       Aug 26, 2021 via iPhone
    用 save 前端会返回这个结构体的时候数据,偶尔会用 update map 来更新
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2424 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 63ms · UTC 04:40 · PVG 12:40 · LAX 21:40 · JFK 00:40
    ♥ Do have faith in what you're doing.