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

为什么 Go 中的 ORM 框架使用起来感觉比较怪异

  •  
  •   cc959798 · 5 天前 · 3312 次点击

    最近研究 Go,做业务系统必然要用到 ORM,毕竟数据库操作太频繁了鞋 SQL 效率太低了

    之前用过很多 ORM,比如 JAVA 中的 hibernate,Python 中的 sqlalchemy,PHP 中的 Yii,感觉 ORM 其实都是大同小异 上面的几乎也是类似的使用方式 但是到了 Go,这里感觉画风骤变,了解了 gorm 和 xorm (这两个其实挺像的),里面不在像之前的通过 model 或者 db 进行 find 查询只需要传入条件返回一个查到的对象,2️⃣必须先要 new 一个对象,然后通过指针传入进去,框架也是感觉比较简单的

    46 回复  |  直到 2018-07-19 15:28:11 +08:00
        1
    ZSeptember   5 天前
    你仔细想想,你不 new 一个给它,它怎么返回一个你要的对象给你
        2
    gowk   5 天前
    ORM 倾向于让系统变得复杂,直接用 sqlx 就好了
        3
    Cbdy   5 天前 via Android
    直接写 SQL,然后 bind 参数,这样是坠吼的
        4
    kunluanbudang   5 天前   ♥ 1
    Go 粉丝 /布道者, 倾向于批判楼主

    ( Go , 整体还不错, 用起来也非常爽,

    但是 Go 粉丝, 一般喜欢无脑吹捧一些陋习, 我比较反感这个 )
        5
    Muninn   5 天前
    go 也可以给你返回给 map[string]interface{},然而不好用啊。。。

    你 new 一个给你智能的填进去反而后边省事了,预定义好,不用你取到后再处理了。
        6
    monsterxx03   5 天前 via iPhone
    go 的 orm 不好用,试试 squirrel + sqlx
        7
    guoziyan   5 天前
    所有的 orm 没有一个直观好用的(所有语言)
        8
    janxin   5 天前 via iPad
    实际上因为没用过 c++/rust 的 orm 吧,go 没有那种贴近动态语言的运行时功能,只能做到这种地步了
        9
    lhx2008   5 天前 via Android
    @guoziyan springboot 的 springjpa+heibernate 用过了吗
        10
    q397064399   5 天前
    @guoziyan #7 springdata jpa 了解一下
        11
    cc959798   5 天前
    @ZSeptember 如果 model 是结构体的话,直接返回一个结构体 变量或者自己内部 new 一个不就可以了
        12
    cc959798   5 天前
    @janxin 都没见过 C++的 ORM
        13
    ZSeptember   5 天前 via Android
    @cc959798 你 new 一个看看,想想
        14
    boyhailong   5 天前
    那可以自己造轮子,用脚本生成代码吧 像 protobuf 那样,虽然很麻烦,加载、查询、保存都可以自己定制。。。。
    公司项目 C++就是那样,不然要麻烦哭
        15
    qsnow6   5 天前
    django orm 了解一下
        16
    ZSeptember   5 天前 via Android
    @janxin rust 还可以用 derive,还好
        17
    xiaqi   5 天前 via Android
    我怎么感觉写 sql 效率还更高呢?
    orm 一些复杂的操作是操作不了的,写 sql,我甚至可以放个存储过程进去,经管这个有时候不推荐。而且写 sql 通用,换了语言也不是很担心,相反,orm 换了语言,有些差别可就大了,你得再去学一遍 orm。
        18
    cc959798   5 天前
    @Muninn 为什么不直接返回一个 model,填充好的
        19
    luob   5 天前
    gorm 作者的意思是为了保持 api 一致
    所有的操作都返回 db 实例,就可以愉快地链式调用,查询结果这种东西只能委屈一下先 new 一个,然后传进去塞值
        20
    dodo2012   5 天前
    @ZSeptember derive 用了下,感觉挺难用啊,难道是姿势不对
        21
    bigpigeon   5 天前
    有一个 orm 方案是生成代码,因为 go 是强类型的,并且不支持模板,所以没法通过返回值取值
        22
    ZSeptember   5 天前
    @dodo2012 derive 就是用 macro 实现的,一般就是操作 ast ;自己写的话确实不好用。用别人写好的,现在的 rust ide 支持还太差了,提示不友好。。
        23
    dodo2012   5 天前
    @ZSeptember vscode 现在用起来还好,v2 居然还有在用 rust 的啊,很少见,,
        24
    janxin   5 天前 via iPad
    @dodo2012 其实挺多的
        25
    cc959798   5 天前
    @luob 这种设计可以用其他方式更改的,比如 select where join 等方法可以返回 DB 实例,可以加个类似的 Query 或者 execute 方法来返回插到的值
        26
    cc959798   5 天前
    @bigpigeon 不是有 interface{}吗
        27
    pubby   5 天前 via Android
    你说的都还好,gorm 最坑的是查询和更新时的零值的处理
        28
    ZSeptember   5 天前 via Android
    @pubby 我觉得设计的没问题,有什么特殊需求也可以用 hook 解决。
        29
    xypcn   5 天前
    https://github.com/ecdiy/gpa 这是我自己实现的 orm,操作与 spring-data-jpa 差不多
        30
    pathbox   5 天前 via iPhone
    sqlx 应该会是好的选择
        31
    dodo2012   5 天前
    @janxin 是不是哟,一直觉得搞 rust 的很少,特别在国内,主要是,学习曲线太,,高了
        32
    youEclipse   5 天前
    @bigpigeon 我用过一个生成代码的 orm 方案,叫 gorp,但是真的很不好用啊。。
        33
    JerryCha   5 天前
    传指针啊,这风格很 C
        34
    glues   5 天前
    用 go 写业务逻辑,要死人的
        35
    ZSeptember   5 天前 via Android
    @xypcn 你这个项目跟我的项目名一模一样。。
        36
    ZSeptember   5 天前 via Android
    感觉大家没有 get 到 LZ 的问题啊。
    LZ 问的是为什么这些框架查询的时候需要 new 一个指针作为参数传为 find 方法,而不是像 jpa 那样作为返回值。
    其实自己尝试写一下就知道了,go 是做不到 jpa 那种的,go 没有泛型,调用的时候拿不到需要返回的类型信息,就不能在 find 方法里面实例化对象。。jpa 能做到,是因为 Java 的反射能拿到泛型特化信息,然后可以用反射实例化对象,再设置属性值的。
        37
    cc959798   5 天前
    @ZSeptember 有道理,Go 的设计感觉还是局限性挺高的,说 Go 的开发效率和脚本语言一样快,真的不敢苟同
        38
    cc959798   5 天前
    @ZSeptember 感觉可以不设计成使用统一 db 去查询的方式,可以类似 python 框架中 Django 中的 ORM,使用 Model 进行查询,Model 只需要继承相应的基类就可以实现这种方式,也类似于 PHP 中很多的类似的框架,比如 YII 中的 ORM
    当然传统的 ORM 几乎都是这两个设计思路
    我个人偏向于后者
        39
    orvice   5 天前
    语言特性限制吧,不能想 py/php 那么灵活。
        40
    mritd   5 天前 via iPhone
    我觉得是语言特性问题,至于传指针,我倒是觉得很好很清晰,java 把指针藏起来倒难受
        41
    xypcn   5 天前
    @ZSeptember 你的方案不好用.我的方案,使用与 java 对比如下:

    定义 SQL

    type SqlAction struct {
    SysRoleDel func(roleId int64, roleId2 int64) (int64, error) `delete from SysRole where id=? and creator!=0 and 0=(SELECT count(*) from SysUserRole where roleId=?)`
    // insert ,delete update 都可以使用
    // select 可以返回 int,int64,string,map[string]string []int,[]......... []map[string]string object 都能反射
    }

    类似 JAVA spring-data interface 定义 SQL


    sqlAction := &SqlAction{}

    orm := GetGpa("mysql", "root:root@tcp(127.0.0.1:3306)/base-sys-user?timeout=30s&charset=utf8&parseTime=true",
    sqlAction)

    golang 没有 java 的注入之类,显示实例化,java 的实例化可以通过注入,这个可以是全局变量

    调用: sqlAction.SysRoleDel(48)

    与 java 一样方便。

    一个 orm 框架,至少要分离 sql 的调用。

    GetDb().Table("model").Find(&model, " id =? ", id) 这种设计肯定是没有理解 java 的 spring-data 接口设计,
    也是很多 java 开发者看起来比较怪异的地方


    @glues go 写业务逻辑与 java 一样方便,只是你不熟悉而已,至少需要一年以上的累积,go 的起步较高,
    它是认为开发者已经精通一门开发语言了,一个好的项目推广比较难,一般是一个公司,或是先发,累积。
        42
    tcp   5 天前 via Android
    我?
        43
    ZSeptember   5 天前 via Android
    @xypcn 我觉得你没看明白。我的是个代码生成器,不是 ORM。生成的规则是 spring-data-jpa 的方法命名,生成的代码是基于 gorm 的,你吐槽的是 gorm 的设计。不过这也是仁者见仁的事情。Java 也有 jooq,这种框架,spring-data-jpa 也有 query DSL 也是这种形式的。
        44
    bigpigeon   5 天前
    @cc959798 返回 interface{}还得强转,还得知道你想要什么类型才能强转,还不如直接传引用来的方便
        45
    my3157   4 天前
    主要还是 go 的 reflect 太弱了
        46
    nocrush   19 小时 23 分钟前
    laravel orm 我觉得是我用过中最好用的
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   实用小工具   ·   2979 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 20ms · UTC 02:52 · PVG 10:52 · LAX 19:52 · JFK 22:52
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1