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

Gopher 我们一起来造个 ORM 吧!

  •  
  •   wenjie0032 · 2022-07-21 11:36:29 +08:00 · 6216 次点击
    这是一个创建于 856 天前的主题,其中的信息可能已经有所发展或是发生改变。

    可能绝大部分搞业务的同学逃不过 CRUD, 在编程中会有大量的工作与数据库打交道

    常见的解决方案一般有以下三种, 1. 原生手写, 2. 开源 orm 类库, 3. 自研 orm 类库

    诉求不同方案也就不同, 开发者在 高性能易用性 之前来回权衡, 做出符合自己实际情况的选择.

    已经有很多优秀的开源库了 awesome-go-orms, 发起这个小活动的目的

    1. 学习如何设计一个对外 API 稳定的开源库
    2. 设计开源库时保持 api 稳定的情况下如果兼顾可扩展性 (自定义类型, Trace, Logger 等等)
    3. 数据模型抽象, 数据可能保存在 MySQL, MongoDB, Es 等不同的 BD, 甚至是三方 API 如果统一支持?
    4. 多跟优秀的人交流(比如正在看帖的你), 见贤思齐.

    我们的思考方式: 我希望能支持 xxx, 这样做的好处是 xxx, 这样做有什么坏处吗, 其他项目是怎么实现的?

    比如:

    1. 我希望能自动构造 SQL 语句, 这样做能灵活控制 SQL 条件, 避免硬编码, 坏处可能是出问题了不好定位 sql...
    2. 我希望能查询条件可以是 method(args ...WhereOption) 的形式, 这样做可以根据请求中的参数动态构造约束, 对比链式调用的优势是..., 缺点是...

    业余也根据以上方式实践了下 fly, 反复修改了很多次, 也尝试了泛型 /反射等的使用, 有很多地方还没有想清楚, 比如数据模型的描述上, 是用 Options 的模式, 还是 Struct tag 的模式, 优劣是什么 等, 这是一个纯学习性的讨论活动, 有兴趣的大佬们进群一起讨论吧.

    这是企微群, 个人微信也可以直接加入, 企微主体是 "爱码士", 我自己建的😂 用这个主要图他这个二维码是活码(其实就是一个中转页面, 进入后出现的那个是系统自动生成的当前可用的群二维码), 不会有 7 天过期(希望帖子能活到 7 天后😝)

    contact_me_qr

    39 条回复    2022-07-22 20:31:17 +08:00
    cxytz01
        1
    cxytz01  
       2022-07-21 12:06:47 +08:00   ❤️ 1
    为什么不使用第四种解决方案:4.给开源 orm 库提交 pr ?
    teasick
        2
    teasick  
       2022-07-21 13:11:26 +08:00
    还以为你要实现一个 gopher
    kwanzaa
        3
    kwanzaa  
       2022-07-21 13:16:48 +08:00   ❤️ 1
    为什么要加微信群
    FrankFang128
        4
    FrankFang128  
       2022-07-21 13:38:12 +08:00   ❤️ 2
    我觉得 nb 的库基本都是一个人实现的,人越多,逼格越低。
    join
        5
    join  
       2022-07-21 13:39:29 +08:00 via iPhone   ❤️ 1
    可别了,gorm 一天到晚 panic ,然后要在外面写 recover 。
    老老实实写 sql 不会死
    kiwi95
        6
    kiwi95  
       2022-07-21 13:59:01 +08:00 via Android
    @join 能分享下 panic 经历吗,在字节内部大量使用 gorm ,单纯因为 gorm 导致 panic 的没怎么见过
    join
        7
    join  
       2022-07-21 14:14:22 +08:00 via iPhone
    @kiwi95 没捕获 err ,大量的 a.b.c 这样的 jave 味代码。
    linshenqi
        8
    linshenqi  
       2022-07-21 14:20:17 +08:00
    一直在用 gorm
    danbai
        9
    danbai  
       2022-07-21 14:40:57 +08:00
    我用 gorm 一般都用 db.raw
    danbai
        10
    danbai  
       2022-07-21 14:43:44 +08:00
    @kiwi95 gorm panic 的情况我只遇到过一种就是传参不对没有传递指针去接收返回。
    seth19960929
        11
    seth19960929  
       2022-07-21 14:51:35 +08:00   ❤️ 1
    说实话就 GoFrame 的 dao 我用的最舒服.
    https://goframe.org/pages/viewpage.action?pageId=7296196
    wenjie0032
        12
    wenjie0032  
    OP
       2022-07-21 15:27:46 +08:00
    @cxytz01 #1 能反馈开源当然是很好的
    @seth19960929 #11 周末研究一下
    IIInsomnia
        13
    IIInsomnia  
       2022-07-21 18:05:52 +08:00
    ent 不香吗?
    ToBeHacker
        14
    ToBeHacker  
       2022-07-21 18:43:36 +08:00
    反射实现一个挺容易的
    lesismal
        15
    lesismal  
       2022-07-21 19:40:11 +08:00
    我不信有哪个比我这个 rawsql 好用:
    https://github.com/lesismal/sqlw

    @join 试试我这个
    zoharSoul
        16
    zoharSoul  
       2022-07-21 20:52:12 +08:00
    最好单表 curd 提供方法, 其他查询写 sql 生成方法是最舒服的
    就和 mybatis 一样.

    全功能 orm 突出一个难用, 还是这只半自动的舒服
    join
        17
    join  
       2022-07-21 20:53:02 +08:00
    @lesismal 小伙子,不是所有人都用 mysql 的
    kkkiio
        18
    kkkiio  
       2022-07-21 22:22:33 +08:00
    之前给公司自研 ORM 包了层 Spring JPA 的 Query Derivation ,用 go generate 做的,不过依赖公司代码就没放到 GitHub 上了,写了篇 blog: https://kkkiio.github.io/team/2022/01/31/stone-soup.html
    EminemW
        19
    EminemW  
       2022-07-21 22:40:07 +08:00
    歪楼问一下,为啥 gorm 没有优化 select * ,还是说有实现但是我没有找到方法
    wenjie0032
        20
    wenjie0032  
    OP
       2022-07-21 23:04:50 +08:00 via iPhone
    @kkkiio 大佬的文章中石头汤的故事很有意义,我也尝试过在公司内部推广一些基础工具,封装的类库,低代码工具等,有些使用广泛,有些则无人问津,可以借助石头汤的方法论复盘一下
    lesismal
        21
    lesismal  
       2022-07-21 23:12:06 +08:00
    @join 我这个也不是只支持 mysql 呀,主要是为了方便标准库 sql 与结构体的映射,并不限制用哪个 driver 。但我不是每个数据库都测了,目前 mysql 和 postgres 是可以的,如果 oracle 、sqlserver 或者其他的数据库有问题(应该只是占位符不一样会导致拼接的 sql 语句错误),我可以继续做兼容。

    另外,不知道兄台多大年纪,但我也已经不是小伙子了。
    lesismal
        22
    lesismal  
       2022-07-21 23:13:53 +08:00
    @lesismal #21
    有兴趣的可以看下例子,再对比下 orm ,或者 sqlx 之类的,看看哪个好用。
    LeegoYih
        23
    LeegoYih  
       2022-07-22 01:17:45 +08:00
    受限于 Go 语言本身,注定就没有好用的 ORM 框架
    realpg
        24
    realpg  
       2022-07-22 02:54:12 +08:00
    等手头项目做完 计划做一个开源轻量查询拼接器,轻 orm

    喷了那么久的 gorm, 不打算总打嘴炮
    Trim21
        25
    Trim21  
       2022-07-22 02:58:50 +08:00 via Android
    @EminemW 优化 select 是指只 select 用到的字段?这个在 gorm.DB 初始化的时候有一个 SelectFileds 的设置
    Trim21
        26
    Trim21  
       2022-07-22 03:00:38 +08:00 via Android
    SQLboiler 看的 API 起来挺舒服,可惜不支持我现在的使用场景,我有几个表恰好他不支持…
    Aloento
        27
    Aloento  
       2022-07-22 03:56:40 +08:00
    @Trim21 捕获 Trim 大佬
    Aloento
        28
    Aloento  
       2022-07-22 03:58:11 +08:00
    真的要整好的 ORM 我只认可 EF Core ,其他的我还不如写 pg/SQL 还跟舒服些
    bthulu
        29
    bthulu  
       2022-07-22 08:09:32 +08:00
    @Aloento efcore 真是垃圾中的垃圾, deleteById 这样的方法都没有, 必须先通过 id 查出来, 再删除, 脱裤子放屁最在行
    cbasil
        30
    cbasil  
       2022-07-22 09:37:12 +08:00
    手写 sql 能有啥问题
    wenjie0032
        31
    wenjie0032  
    OP
       2022-07-22 09:51:45 +08:00   ❤️ 1
    @seth19960929 , @lesismal , @kkkiio , @Trim21 , @Aloento 感谢评论区大佬们的推荐, 看下来比较喜欢 GoFrame 和 SQLboiler 的实现理念, orm 这种工具实在是重口难调😂, 从我了解到的情况来看, 大部分公司是自研或基于开源项目自研,
    也许其中有很多结合自身情况的考量, 后续我会持续迭代个人项目 https://github.com/daodao97/fly, 最起码先自用比较舒服吧, 也算是一个学习积累的过程

    额外: GoFrame 的文档写的真心不错, 点赞
    rickiey
        32
    rickiey  
       2022-07-22 10:15:45 +08:00
    gorm 除了 Create 可以批量创建,其他全部手写 sql, raw 或 exec 执行,结果 Scan ,目前没问题,有时 update 时会用 map
    tairan2006
        33
    tairan2006  
       2022-07-22 10:16:26 +08:00
    ent 设计的不错,不过真用起来还是 sqlbuilder 一把梭
    rickiey
        34
    rickiey  
       2022-07-22 10:16:46 +08:00   ❤️ 1
    其实我只需要一个能把结果自动映射到我的 go 结构体的框架就够了
    mizuhashi
        35
    mizuhashi  
       2022-07-22 13:11:11 +08:00
    做之前建议先用用 rails 的 activerecord 体验一下
    StarkWhite
        36
    StarkWhite  
       2022-07-22 15:48:33 +08:00
    @tairan2006 ent 是指 fb 新出的那个 orm 库吗?
    tairan2006
        37
    tairan2006  
       2022-07-22 15:58:45 +08:00
    @StarkWhite 嗯,对
    StarkWhite
        38
    StarkWhite  
       2022-07-22 17:00:58 +08:00
    没用过,我用过 prisma, sequelize, typeorm 这些
    Aloento
        39
    Aloento  
       2022-07-22 20:31:17 +08:00
    @bthulu 可以看看社区的扩展方法,你说的都在扩展方法里面实现了,建议多用用再来发言
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2673 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:17 · PVG 18:17 · LAX 02:17 · JFK 05:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.