V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
jinzhu
V2EX  ›  Go 编程语言

GORM v2 正式发布! 20k stars ;)

  •  
  •   jinzhu · 2020-08-31 06:21:43 +08:00 · 13300 次点击
    这是一个创建于 1549 天前的主题,其中的信息可能已经有所发展或是发生改变。

    GORM 2.0 从零开始重写,根据过去几年的用户反馈吐槽,做了大量的改进,历经半年终于达成 ;)

    主要更新

    • 性能改进
    • 代码模块化
    • Context,批量插入,预编译模式,DryRun 模式,Join 预加载,Find To Map,Create From Map,FindInBatches
    • 支持嵌套事务,SavePoint,Rollback To SavePoint
    • SQL 生成器,命名参数,分组条件,Upsert,锁, 支持 Optimizer/Index/Comment Hint,子查询改进,使用 SQL 表达式、Context Valuer 进行 CRUD
    • 支持完整的自引用,改进 Join Table,批量数据的关联模式
    • 允许多个字段用于追踪 create 、update 时间 ,支持 UNIX (毫 /纳)秒
    • 支持字段权限:只读、只写、只创建、只更新、忽略
    • 新的插件系统,为多个数据库提供了官方插件,读写分离,prometheus 集成...
    • 全新的 Hook API:带插件的统一接口
    • 全新的 Migrator:允许为关系创建数据库外键,更智能的 AutoMigrate,支持约束、检查器,增强索引支持
    • 全新的 Logger:支持 context 、改进可扩展性
    • 统一命名策略:表名、字段名、连接表名、外键、检查器、索引名称规则
    • 更好的自定义类型支持(例如:JSON )

    详情请参考 Release Note

    https://gorm.io/zh_CN/docs/v2_release_note.html

    100 条回复    2020-12-28 10:19:38 +08:00
    SteinsGate
        1
    SteinsGate  
       2020-08-31 06:29:33 +08:00 via Android   ❤️ 1
    好喔
    snxq1995
        2
    snxq1995  
       2020-08-31 06:47:14 +08:00 via Android
    赞👍
    lrh3321
        3
    lrh3321  
       2020-08-31 06:56:28 +08:00 via Android
    update 的时候,忽略 limit 和 order by 的问题还存在吗?
    gigantic222
        4
    gigantic222  
       2020-08-31 07:59:13 +08:00
    kemikemian
        5
    kemikemian  
       2020-08-31 08:16:29 +08:00
    赞赞赞!!!
    kemikemian
        6
    kemikemian  
       2020-08-31 08:22:19 +08:00
    终于加入了批量新增
    paullee
        7
    paullee  
       2020-08-31 08:51:04 +08:00   ❤️ 2
    诸位大佬,小弟有一问求教,查询记录不存在时,大佬们都是在哪一层处理它呀?

    小弟现在是在业务层使用 gorm.isRecordNotFound()对 gorm 查询返回的错误判断一记,之前也尝试过在查询方法中返回(*data, *error),将记录未找到的错误场景处理为返回(nil, nil)。两种都感觉怪怪的。
    momowei
        8
    momowei  
       2020-08-31 08:53:26 +08:00
    牛,项目正好用 1 刚开始,切换到 2 看看
    wsseo
        9
    wsseo  
       2020-08-31 09:02:49 +08:00
    在线等 3.0
    Yoock
        10
    Yoock  
       2020-08-31 09:08:10 +08:00 via iPhone
    一会试试
    waising
        11
    waising  
       2020-08-31 09:17:32 +08:00
    支持一波
    cloudzhou
        12
    cloudzhou  
       2020-08-31 09:25:44 +08:00
    我对 gorm 最大的体验是,作者应该有很强的函数化编程背景,所以很重度使用函数化,各种 hook
    而我对于中间件类型代码,是很反对函数化
    我对中间件类型代码的要求,就是 Go 本身源代码,我一眼看下去就知道在做什么
    aladdindingding
        13
    aladdindingding  
       2020-08-31 09:31:51 +08:00
    顶!
    zhaoxj58
        14
    zhaoxj58  
       2020-08-31 09:36:36 +08:00 via iPhone
    赞楼主👍
    FEDT
        15
    FEDT  
       2020-08-31 09:49:42 +08:00
    赞一个~
    securityCoding
        16
    securityCoding  
       2020-08-31 10:06:42 +08:00
    @cloudzhou jinzhu 什么背景啊,很强...
    dany813
        17
    dany813  
       2020-08-31 10:08:11 +08:00
    厉害
    Hanggi
        18
    Hanggi  
       2020-08-31 10:13:23 +08:00
    已经在用了
    guanhui07
        19
    guanhui07  
       2020-08-31 10:16:22 +08:00
    赞赞赞!!!
    pkoukk
        20
    pkoukk  
       2020-08-31 10:16:32 +08:00
    用 v1 的项目写到一半,周一来一看更新到 v2 了,我是迁移还是不迁移呢
    ghjacky
        21
    ghjacky  
       2020-08-31 10:17:24 +08:00
    一直在用 gorm,赞👍!!!
    ylsc633
        22
    ylsc633  
       2020-08-31 10:26:32 +08:00
    不知道多对多查询 那个问题还存在不
    不过 还是赞一个
    jamry
        23
    jamry  
       2020-08-31 10:31:56 +08:00
    顶一个
    还在等大牛推出稳定的 oracle dialector
    Hancock
        24
    Hancock  
       2020-08-31 11:02:33 +08:00
    批量终于来了😭
    qxqsxbd
        25
    qxqsxbd  
       2020-08-31 11:19:37 +08:00
    刚上线个项目用了 v1
    labulaka521
        26
    labulaka521  
       2020-08-31 11:28:51 +08:00
    blless
        27
    blless  
       2020-08-31 11:35:00 +08:00 via Android
    delete 的时候没有参数还会把整张表删掉吗?当年因为这个事一直不敢用 gorm
    blless
        28
    blless  
       2020-08-31 11:36:46 +08:00 via Android
    应该说删除的时候,因为默认结构体没有赋值,所以一不小心就把整表删了
    Kr98
        29
    Kr98  
       2020-08-31 11:43:16 +08:00 via Android
    @blless update 也有这种问题,我一开始的理解是这种情况应该返回错误,结果 gorm 直接对整张表进行操作
    ZSeptember
        30
    ZSeptember  
       2020-08-31 11:50:11 +08:00
    很喜欢 gorm 的设计,完全的插件化,定制化太强了额。对我自己项目的设计也有很大的启发。
    blless
        31
    blless  
       2020-08-31 11:54:28 +08:00 via Android
    @Kr98 所以当时发现这个情况,就不敢在线上用,然后换了 xorm
    zackkson1991
        32
    zackkson1991  
       2020-08-31 12:55:25 +08:00
    赞!
    imherer
        33
    imherer  
       2020-08-31 13:45:18 +08:00
    @paullee 我一般的是在 model 层处理

    我一般的做法是:例如用 UID 查询,当记录不存在的时候返回 nil,同时 user.UID = 0,上一次判断 user.UID 是否等于 0 来判断记录存不存在

    不过感觉好像也不是很好
    dcalsky
        34
    dcalsky  
       2020-08-31 13:49:31 +08:00
    Preload("articles")以前如果是空会返回空数组,现在直接变 null 了。感觉有问题
    justin2018
        35
    justin2018  
       2020-08-31 13:50:41 +08:00
    ![yUBe256]( )

    还有英文介绍~
    kosgug
        36
    kosgug  
       2020-08-31 13:57:38 +08:00 via iPhone   ❤️ 1
    居然作者直接来推,现在一直用 entgo,有没有对比过
    owenliang
        37
    owenliang  
       2020-08-31 13:59:57 +08:00
    支持,一直在用。
    blackeeper
        38
    blackeeper  
       2020-08-31 14:07:46 +08:00
    一直在用,作者牛皮!
    yiplee
        39
    yiplee  
       2020-08-31 14:55:46 +08:00
    升级之后手动创建 index 的方法 db.AddIndex 和 db.AddUniqueIndex 找不到了
    back0893
        40
    back0893  
       2020-08-31 15:28:36 +08:00
    @pkoukk 一样,纠结.中
    hduwillsky
        41
    hduwillsky  
       2020-08-31 15:46:58 +08:00
    Jinzhu 大佬 NB
    jinzhu
        42
    jinzhu  
    OP
       2020-08-31 18:34:30 +08:00   ❤️ 1
    @lrh3321 已经修复了,需要使用最新的 mysql driver,不过这种特性只有 mysql 支持,其它数据库都不可以
    jinzhu
        43
    jinzhu  
    OP
       2020-08-31 18:35:11 +08:00
    @paullee 用的 Find ?没找到数据不返回错误,判断下 RowsAffected
    jinzhu
        44
    jinzhu  
    OP
       2020-08-31 18:37:37 +08:00
    @cloudzhou 函数化为了提供一些扩展可能性,在一些场景下还是挺需要的,不过排斥这个的话也没有关系,甚至可以用 GORM 的 raw sql 模式,他对 named argument 之类的支持应该也比其它的 sql builder 好一些,并且也不重
    jinzhu
        45
    jinzhu  
    OP
       2020-08-31 18:38:41 +08:00
    @pkoukk 肯定迁移呀,V2 和 V1 比改善巨大 ;)
    jinzhu
        46
    jinzhu  
    OP
       2020-08-31 18:39:26 +08:00
    @blless V1 有个 BlockGlobalUpdate 模式,可以启用这个模式就不会了,V2 现在是默认选项了,默认不会删除 /更新全表
    jinzhu
        47
    jinzhu  
    OP
       2020-08-31 18:40:48 +08:00
    @ylsc633 不知道你说的啥问题。。。对于关联的代码全部重写了,新的逻辑比之前的代码对边缘情况处理好很多
    jinzhu
        48
    jinzhu  
    OP
       2020-08-31 18:41:08 +08:00
    @jamry 有个小伙伴在写这个了,貌似进展还不错
    jinzhu
        49
    jinzhu  
    OP
       2020-08-31 18:42:33 +08:00   ❤️ 1
    @Kr98 V1 有个 BlockGlobalUpdate 模式,可以启用这个模式就不会了,V2 现在是默认选项了,默认不会删除 /更新全表
    jinzhu
        50
    jinzhu  
    OP
       2020-08-31 18:45:15 +08:00
    @dcalsky 现在直接变 null 了是什么意思? Articles 是一个 slice 的指针?
    jinzhu
        51
    jinzhu  
    OP
       2020-08-31 18:46:03 +08:00   ❤️ 1
    @yiplee 现在 migrator 更强大了, 参考 https://gorm.io/docs/migration.html
    dobelee
        52
    dobelee  
       2020-08-31 19:14:34 +08:00 via iPhone
    每天都在代码里看到大佬的 ID 。膜拜一下。
    tomtiddler
        53
    tomtiddler  
       2020-08-31 20:09:44 +08:00
    看了下文档,不创建外键的情况下还是无法使用关联是吗。。。😓
    tomtiddler
        54
    tomtiddler  
       2020-08-31 20:11:44 +08:00
    哦,支持不创建外键了。。。看到了,藏得有点深。😺
    zibber
        55
    zibber  
       2020-08-31 21:19:21 +08:00
    各位,分表有什么最佳实践
    jinzhu
        56
    jinzhu  
    OP
       2020-08-31 21:49:46 +08:00
    @zibber 使用 Scopes 这个方法来分表,其它读写分离之类的可以参考 https://gorm.io/docs/dbresolver.html
    lekai63
        57
    lekai63  
       2020-08-31 22:25:37 +08:00 via iPhone
    v2 版本 beta 的时候就开始用啦 :)
    yrj
        58
    yrj  
       2020-08-31 23:52:45 +08:00 via iPad
    支持链式设置表别名了嘛,我记得 v1 是不行的
    fy
        59
    fy  
       2020-09-01 00:41:26 +08:00
    近距离接触大佬,支持一下
    mscb
        60
    mscb  
       2020-09-01 06:34:57 +08:00 via Android
    请问一下,就是 gorm 里面的 offset 和 limit 它们要求传入的是 int 型。可是表行数有可能会超过 int 的范围,按理说应该得接受传入 int64 比较合理。请问这边这样设计是有啥原因吗?
    lrh3321
        61
    lrh3321  
       2020-09-01 08:42:03 +08:00 via Android
    @mscb #60 这么大的 offset 和 limit,你不考虑先分库分表或者优化别的地方吗
    qs2d
        62
    qs2d  
       2020-09-01 08:49:27 +08:00
    一直在用,果断升级
    chengxiao
        63
    chengxiao  
       2020-09-01 09:52:33 +08:00
    支持下,不过什么时候 Oracle 能被支持呢?最近被 Oracle 折腾的死去活来的
    mscb
        64
    mscb  
       2020-09-01 09:53:09 +08:00 via Android
    @lrh3321 我知道过大的 offset 会有性能问题,但是这不应该是我考虑的事情嘛?底层通用框架的话不应该管的这么宽啊~期待作者回复
    jinzhu
        65
    jinzhu  
    OP
       2020-09-01 10:17:57 +08:00
    @mscb int 在 64 位机器上和 int64 一样的(现在应该都是 64 位机器了吧?)
    jinzhu
        66
    jinzhu  
    OP
       2020-09-01 10:19:50 +08:00
    @chengxiao 有个相关 PR https://github.com/go-gorm/gorm/pull/3338 , 可以帮测试下看看
    andyangyu
        67
    andyangyu  
       2020-09-01 10:57:14 +08:00
    有没有升级需要注意的事项呢?
    wangdk23411
        68
    wangdk23411  
       2020-09-01 11:04:53 +08:00
    赞,赶紧测试
    skadi
        70
    skadi  
       2020-09-01 11:41:55 +08:00
    终于 v2 了么? 隐藏坑点有讲明么?
    mscb
        71
    mscb  
       2020-09-01 12:01:22 +08:00 via Android
    @jinzhu 这样的话,确实也是~
    hijoker
        72
    hijoker  
       2020-09-01 12:40:10 +08:00
    批量插入终于支持了么
    tozp
        73
    tozp  
       2020-09-01 12:45:37 +08:00
    可以用在生产环境了嘛?
    ooh
        74
    ooh  
       2020-09-01 13:23:32 +08:00
    所以可以获取 SQL 查询语句了?
    JeromeCui
        75
    JeromeCui  
       2020-09-01 13:41:29 +08:00
    牛逼牛逼
    barbery
        76
    barbery  
       2020-09-01 14:09:56 +08:00
    不错不错,go 的项目一直用这个库
    jinzhu
        77
    jinzhu  
    OP
       2020-09-01 15:16:59 +08:00
    @ooh https://gorm.io/docs/session.html#DryRun 可以通过这个模式获取
    @hijoker en
    @tozp 现在已经有几百个线上服务在踩雷了 ;)
    vZexc0m
        78
    vZexc0m  
       2020-09-01 15:56:46 +08:00
    感觉自动迁移有问题,不知道是不是 tag 没有设置好。

    一是会多次对同一字段多次创建索引(mobile),二是会不断迁移未更改的字段。
    windghoul
        79
    windghoul  
       2020-09-01 17:34:07 +08:00
    好哦~
    ooh
        80
    ooh  
       2020-09-01 19:43:24 +08:00
    @jinzhu 牛皮牛皮,之前一直纠结这个
    jinzhu
        81
    jinzhu  
    OP
       2020-09-01 21:05:48 +08:00
    @vZexc0m 确实可以复现 modify column 这个,已经修复,感谢!
    tairan2006
        82
    tairan2006  
       2020-09-02 00:27:49 +08:00 via Android
    我其实一直有个疑问,楼主为啥 id 叫金主(
    yianing
        83
    yianing  
       2020-09-02 01:41:31 +08:00 via Android
    @lrh3321 今天就遇见这个问题了😂更新一下 gorm.io/driver 就行了
    petelin
        84
    petelin  
       2020-09-02 08:20:43 +08:00 via iPhone
    是我在各个语言里遇到的最难用的 orm 。
    而且因为 start 太多 导致其他人不愿意去写一个类似的库。毕竟这个东西更大消耗是在维护上。

    我怀疑作者根本没看过其他 orm 的实现,或者一开始没有投入什么精力,一厢情愿的提供了零碎的东西,写着玩玩,可以称之为玩具。敢用在生产环境也的人也是疯了。

    只针对 gorm1,gorm2 还没看。
    jinzhu
        85
    jinzhu  
    OP
       2020-09-02 10:21:37 +08:00
    @petelin Go 的 ORM 还真不少

    > 我怀疑作者根本没看过其他 orm 的实现,或者一开始没有投入什么精力,一厢情愿的提供了零碎的东西,写着玩玩,可以称之为玩具。敢用在生产环境也的人也是疯了。

    现在可以直接喷,不列证据了么?
    wnanbei
        86
    wnanbei  
       2020-09-02 11:30:30 +08:00
    @jinzhu 哈哈,消消气,有些人是这样的
    j2gg0s
        87
    j2gg0s  
       2020-09-02 12:47:10 +08:00
    @pkoukk 迁移把,用新不用旧。流量不是特别大的,应该也踩不到什么极端的坑
    LudwigWS
        88
    LudwigWS  
       2020-09-02 13:30:55 +08:00
    大佬我插个题外话。

    你现在都转用 Jetbrains 的产品呢了么。这几年 Emacs 和 Vim dot file 都没怎么更新。以前看到你说从 Vim 转 Emacs 了,现在是不是又回去 Vim 了。纯属好奇。😂
    jinzhu
        89
    jinzhu  
    OP
       2020-09-02 13:48:58 +08:00
    @LudwigWS 现在 tmux + vim 用的挺爽的。。。之前 emacs 试了一段时间,可能单进程的原因导致经常卡,就回到 vim 了,现在个人配置文件放私有仓库了... 所以没更新。。。
    blakejia
        90
    blakejia  
       2020-09-02 15:50:13 +08:00
    最新版本啥时候发布呢?遇到了这个问题。看到是已经解决了。但是没发

    Gorm writes wrong SQL when trying to alter existing column for PostgreSQL

    https://github.com/go-gorm/gorm/issues/3339
    KickAssTonight
        91
    KickAssTonight  
       2020-09-02 16:13:09 +08:00
    支持,可以在查询前 WithContext 了!
    pkoukk
        92
    pkoukk  
       2020-09-02 17:13:34 +08:00
    @petelin go 没有泛型,你说说咋实现你所说的其它语言 orm 的功能?...
    jinzhu
        93
    jinzhu  
    OP
       2020-09-02 20:36:48 +08:00
    @blakejia 等再多收集几天的问题一起发个版吧
    blakejia
        94
    blakejia  
       2020-09-03 14:29:00 +08:00
    @jinzhu #93 对了。好像对 big.Int 或者 big.Float 目前还不支持么?测试了下。读取的时候报
    unsupported Scan, storing driver.Value type string into type *big.Int
    ysongyang
        95
    ysongyang  
       2020-09-03 16:28:13 +08:00
    自定义预加载报错:invalid query condition,是我用法不对吗? https://www.v2ex.com/t/703904#reply0
    ccxx
        96
    ccxx  
       2020-09-06 12:48:12 +08:00 via iPhone
    @jinzhu 请问查询单个字段怎么 scan 到变量而不是结构体,文档的例子 scan 到 int 类型的变量可以,但是数据库查询 varchar 的字段 scan 到 steing 类型的变量不行。
    Aoang
        97
    Aoang  
       2020-09-26 17:03:02 +08:00 via Android
    @jinzhu 现在 Gorm 是不是不需要手动关闭连接了。
    V1 有 db.Close(),V2 好像得 db.DB() 拿到 sql.DB 之后进行关闭。

    关闭这个步骤在 V2 里面不再是必须的了?
    jinzhu
        98
    jinzhu  
    OP
       2020-09-27 15:08:37 +08:00
    @ccxx 最新版本应该可以了

    @Aoang 其实对于大多数应用 v1 版本也不需要 Close,用连接池就好了,好多人用错,于是直接把 Close 方法去掉了,刚需 Close 的人应该也能从文档里找到怎么用
    wuqingdzx
        99
    wuqingdzx  
       2020-11-19 10:32:01 +08:00
    1.20.6 还没有 CreateInBatches 这个方法
    kennry
        100
    kennry  
       2020-12-28 10:19:38 +08:00
    @jinzhu
    问题一:v2 版本添加索引值只能在对象的 tag 添加吗,手动进行迁移时不能和 v1 一样单独添加吗,这样添加多个索引时对象 tag 会很长,而且 gorm.Model 软删除的字段也添加不进联合索引
    问题二:自动迁移时添加外键关联会把外键的相关结构体的外键字段数据库生成时会自动生成为 bigint 类型,而不是我关联结构体定义的类型,这个怎么破?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3431 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 11:15 · PVG 19:15 · LAX 03:15 · JFK 06:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.