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

Gopher 我们一起来造个 ORM 吧!

  •  
  •   wenjie0032 · 70 天前 · 4776 次点击
    这是一个创建于 70 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    @join 试试我这个
    zoharSoul
        16
    zoharSoul  
       70 天前
    最好单表 curd 提供方法, 其他查询写 sql 生成方法是最舒服的
    就和 mybatis 一样.

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

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

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

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