最近研究 Go,做业务系统必然要用到 ORM,毕竟数据库操作太频繁了鞋 SQL 效率太低了
之前用过很多 ORM,比如 JAVA 中的 hibernate,Python 中的 sqlalchemy,PHP 中的 Yii,感觉 ORM 其实都是大同小异 上面的几乎也是类似的使用方式 但是到了 Go,这里感觉画风骤变,了解了 gorm 和 xorm (这两个其实挺像的),里面不在像之前的通过 model 或者 db 进行 find 查询只需要传入条件返回一个查到的对象,2️⃣必须先要 new 一个对象,然后通过指针传入进去,框架也是感觉比较简单的
1
ZSeptember 2018-07-14 12:03:48 +08:00
你仔细想想,你不 new 一个给它,它怎么返回一个你要的对象给你
|
2
gowk 2018-07-14 12:07:03 +08:00
ORM 倾向于让系统变得复杂,直接用 sqlx 就好了
|
3
Cbdy 2018-07-14 12:14:49 +08:00 via Android
直接写 SQL,然后 bind 参数,这样是坠吼的
|
4
kunluanbudang 2018-07-14 12:21:11 +08:00 1
Go 粉丝 /布道者, 倾向于批判楼主
( Go , 整体还不错, 用起来也非常爽, 但是 Go 粉丝, 一般喜欢无脑吹捧一些陋习, 我比较反感这个 ) |
5
Muninn 2018-07-14 12:28:55 +08:00
go 也可以给你返回给 map[string]interface{},然而不好用啊。。。
你 new 一个给你智能的填进去反而后边省事了,预定义好,不用你取到后再处理了。 |
6
monsterxx03 2018-07-14 12:32:33 +08:00 via iPhone
go 的 orm 不好用,试试 squirrel + sqlx
|
7
guoziyan 2018-07-14 14:02:46 +08:00
所有的 orm 没有一个直观好用的(所有语言)
|
8
janxin 2018-07-14 14:26:23 +08:00 via iPad
实际上因为没用过 c++/rust 的 orm 吧,go 没有那种贴近动态语言的运行时功能,只能做到这种地步了
|
10
q397064399 2018-07-14 14:46:09 +08:00
@guoziyan #7 springdata jpa 了解一下
|
11
cc959798 OP @ZSeptember 如果 model 是结构体的话,直接返回一个结构体 变量或者自己内部 new 一个不就可以了
|
13
ZSeptember 2018-07-14 15:15:35 +08:00 via Android
@cc959798 你 new 一个看看,想想
|
14
boyhailong 2018-07-14 15:18:46 +08:00
那可以自己造轮子,用脚本生成代码吧 像 protobuf 那样,虽然很麻烦,加载、查询、保存都可以自己定制。。。。
公司项目 C++就是那样,不然要麻烦哭 |
15
qsnow6 2018-07-14 15:22:06 +08:00
django orm 了解一下
|
16
ZSeptember 2018-07-14 15:25:44 +08:00 via Android
@janxin rust 还可以用 derive,还好
|
17
xiaqi 2018-07-14 15:29:35 +08:00 via Android
我怎么感觉写 sql 效率还更高呢?
orm 一些复杂的操作是操作不了的,写 sql,我甚至可以放个存储过程进去,经管这个有时候不推荐。而且写 sql 通用,换了语言也不是很担心,相反,orm 换了语言,有些差别可就大了,你得再去学一遍 orm。 |
19
luob 2018-07-14 16:03:59 +08:00
gorm 作者的意思是为了保持 api 一致
所有的操作都返回 db 实例,就可以愉快地链式调用,查询结果这种东西只能委屈一下先 new 一个,然后传进去塞值 |
20
dodo2012 2018-07-14 16:39:15 +08:00
@ZSeptember derive 用了下,感觉挺难用啊,难道是姿势不对
|
21
bigpigeon 2018-07-14 16:51:42 +08:00
有一个 orm 方案是生成代码,因为 go 是强类型的,并且不支持模板,所以没法通过返回值取值
|
22
ZSeptember 2018-07-14 17:12:48 +08:00
@dodo2012 derive 就是用 macro 实现的,一般就是操作 ast ;自己写的话确实不好用。用别人写好的,现在的 rust ide 支持还太差了,提示不友好。。
|
23
dodo2012 2018-07-14 17:14:25 +08:00
@ZSeptember vscode 现在用起来还好,v2 居然还有在用 rust 的啊,很少见,,
|
25
cc959798 OP @luob 这种设计可以用其他方式更改的,比如 select where join 等方法可以返回 DB 实例,可以加个类似的 Query 或者 execute 方法来返回插到的值
|
27
pubby 2018-07-14 21:20:06 +08:00 via Android
你说的都还好,gorm 最坑的是查询和更新时的零值的处理
|
28
ZSeptember 2018-07-14 21:24:09 +08:00 via Android
@pubby 我觉得设计的没问题,有什么特殊需求也可以用 hook 解决。
|
29
xypcn 2018-07-14 21:27:22 +08:00
https://github.com/ecdiy/gpa 这是我自己实现的 orm,操作与 spring-data-jpa 差不多
|
30
pathbox 2018-07-14 22:36:11 +08:00 via iPhone
sqlx 应该会是好的选择
|
32
youEclipse 2018-07-14 23:47:11 +08:00
@bigpigeon 我用过一个生成代码的 orm 方案,叫 gorp,但是真的很不好用啊。。
|
33
JerryCha 2018-07-15 00:31:10 +08:00
传指针啊,这风格很 C
|
34
glues 2018-07-15 00:40:16 +08:00
用 go 写业务逻辑,要死人的
|
35
ZSeptember 2018-07-15 00:49:32 +08:00 via Android
@xypcn 你这个项目跟我的项目名一模一样。。
|
36
ZSeptember 2018-07-15 00:57:23 +08:00 via Android 1
感觉大家没有 get 到 LZ 的问题啊。
LZ 问的是为什么这些框架查询的时候需要 new 一个指针作为参数传为 find 方法,而不是像 jpa 那样作为返回值。 其实自己尝试写一下就知道了,go 是做不到 jpa 那种的,go 没有泛型,调用的时候拿不到需要返回的类型信息,就不能在 find 方法里面实例化对象。。jpa 能做到,是因为 Java 的反射能拿到泛型特化信息,然后可以用反射实例化对象,再设置属性值的。 |
37
cc959798 OP @ZSeptember 有道理,Go 的设计感觉还是局限性挺高的,说 Go 的开发效率和脚本语言一样快,真的不敢苟同
|
38
cc959798 OP @ZSeptember 感觉可以不设计成使用统一 db 去查询的方式,可以类似 python 框架中 Django 中的 ORM,使用 Model 进行查询,Model 只需要继承相应的基类就可以实现这种方式,也类似于 PHP 中很多的类似的框架,比如 YII 中的 ORM
当然传统的 ORM 几乎都是这两个设计思路 我个人偏向于后者 |
39
orvice 2018-07-15 01:22:16 +08:00
语言特性限制吧,不能想 py/php 那么灵活。
|
40
mritd 2018-07-15 07:18:55 +08:00 via iPhone
我觉得是语言特性问题,至于传指针,我倒是觉得很好很清晰,java 把指针藏起来倒难受
|
41
xypcn 2018-07-15 09:14:28 +08:00
@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 2018-07-15 09:24:44 +08:00 via Android
我?
|
43
ZSeptember 2018-07-15 09:35:39 +08:00 via Android
@xypcn 我觉得你没看明白。我的是个代码生成器,不是 ORM。生成的规则是 spring-data-jpa 的方法命名,生成的代码是基于 gorm 的,你吐槽的是 gorm 的设计。不过这也是仁者见仁的事情。Java 也有 jooq,这种框架,spring-data-jpa 也有 query DSL 也是这种形式的。
|
45
my3157 2018-07-15 22:22:19 +08:00
主要还是 go 的 reflect 太弱了
|
46
nocrush 2018-07-19 15:28:11 +08:00
laravel orm 我觉得是我用过中最好用的
|