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

GGM: 首个 Gloang 泛型 ORM 库发布 🚀

  •  
  •   wenjie0032 · 2022-03-18 22:35:24 +08:00 · 2986 次点击
    这是一个创建于 1007 天前的主题,其中的信息可能已经有所发展或是发生改变。

    github 直达 github.com/daodao97/ggm

    欢迎大佬们多多指点, 给个 Star.

    包含泛型特性的 go1.18 已经正式发布, 于是就迫不及待的体验了一把.

    我们来看下日常的 db 交互中, 使用泛型, 将会带来哪些便利.

    以下为伪代码, 仅做示意.

    // 预定义的结构体
    type User struct{
    	Id      int    `db:"id"`
    	Name    string `db:"name"`
    }
    

    database/sql 的原生写法

    db := sql.Open()
    
    stmt, err := db.Prepare(sql)
    if err != nil {
    	return
    }
    
    rows, err := stmt.Query(args...)
    if err != nil {
    	return
    }
    
    var list []*User
    for rows.Next() {
    	tmp := new(User)
        rows.Scan(tmp.Id, tmp.User)
        list = append(list, tmp)
    }
    
    

    原生写法相对比较繁琐, 可能一般项目中不会作为首选方案.

    稍微封装下的 db 类库

    
    db = xxx.Conn()
    
    var list []*User
    
    _ = db.Query(sql, &list)
    
    for _, u := range list {
    	fmt.Println(u.Id)
    }
    
    

    可以看出, 相对于原生写法, 代码已经十分简洁, 但是我们不得不提前定义 var list []*User

    并且需要将其已指针形式 &list 传入类库, 熟悉其他语言的同学就会觉得这里看起来十分蹩脚了.

    泛型的 db 类库

    
    list, _ := ggm.New[User]().Select(sql)
    
    for _, u := range list {
    	fmt.Println(u.Id)
    }
    

    在泛型类库中, 查询后, 无需任何转换 list 的类型已经是 []User.

    相对于第二写种法, 代码又精进了异步, 更加的简洁直观了.

    传送门

    github 直达 github.com/daodao97/ggm

    欢迎大佬们多多指点, 给个 Star.

    7 条回复    2022-03-22 15:39:04 +08:00
    GeruzoniAnsasu
        1
    GeruzoniAnsasu  
       2022-03-19 04:33:02 +08:00   ❤️ 1
    …… 无恶意,你看过 GORM 的源码吗



    当执行一个查询的时候,model 一定是「有类型」的,所以在设计查询接口的时候,目标并不是抹除输入数据的类型差异,相反还要要提取出输入的类型特征加以处理。所以 gorm 用 interface{}来接纳任意类型后用了大量反射手段去还原 interface 的具体 <模型或类型> 是啥


    之前看过有个大佬写的博客感觉很有启发,泛型能改善的最大问题是高阶函数:

    func (S) filter (d []type1, f func (e type1) bool ) []type1

    func (S) filter (d []type2, f func (e type2) bool ) []type2
    是两个不同的函数。但有了泛型,可以只写一次。
    https://go.dev/play/p/OHdhzMstFxW

    我感觉 拼一套低配 LINQ 还是挺有可能而且有意义的
    kaichen
        2
    kaichen  
       2022-03-19 09:20:28 +08:00
    最近这个仓库的星星上升很快

    https://github.com/samber/lo

    之前范型未出来之前好几个 FP 库用的人少,其中不受还被作者自己弃库了,现在可能会变得不同
    bthulu
        3
    bthulu  
       2022-03-19 10:44:34 +08:00
    不要泛型, 泛型是异端, 统统烧死
    wenjie0032
        4
    wenjie0032  
    OP
       2022-03-19 13:01:45 +08:00
    @GeruzoniAnsasu 赞同大佬的观点, 泛型确实会对工具类函数很有帮助, 能显著的减少代码量, 比如 2 楼大佬贴的 lo 库,

    ggm 内部也会用反射去解析下当前 struct 的属性, 并未看过 gorm 的源码, 私以为跟 sqlx 类的 底层原理应该是相似的.

    此处也只是泛型出来后的上手实践, 玩玩儿嘛
    wenjie0032
        5
    wenjie0032  
    OP
       2022-03-19 13:08:18 +08:00
    @bthulu 新鲜事物还是要接受一下的, 哈哈
    raaaaaar
        6
    raaaaaar  
       2022-03-19 14:34:42 +08:00 via Android
    尴尬了,我的 stl 库看来这下要大改了
    wwaayyaa
        7
    wwaayyaa  
       2022-03-22 15:39:04 +08:00
    @GeruzoniAnsasu 赞同,其实这次泛型出来了,我最兴奋的就是我可以更快的撸业务了。
    所以写了一个包,各位大佬可以看看。

    https://v2ex.com/t/842117

    https://github.com/wwaayyaa/go-collection
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1454 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 17:12 · PVG 01:12 · LAX 09:12 · JFK 12:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.