Your Question

文章链接 * https://cloud.tencent.com/developer/article/2056863

The document you expected this should be explained

Expected answer

字节跳动内部微服务在使用gorm作为持久层框架嘛,gorm相比sqlx的优势有哪些呢?

Comment From: ivila

@fineCoderWithLove 额,这两个甚至不是同一种工具包,为什么会拉着比较呢。 sqlx本质上只是对golang原生的sql做了一下拓展,补上了一些比较方便的功能,比如支持In的查询,支持查询结果反序列化到结构体上,但是就这样了。 而gorm是一个orm框架,除了sqlx支持的功能外,它还要支持sql构建,支持业务适配,支持方便的追踪与调试(Logger),支持各种各样的高级功能等等。 然后避免sql注入其实两者都可以,这东西就跟你用的框架没什么关系,是你的数据库支持的,框架只是帮你简化了写法而已。

我可以举两个场景,你看看用哪个框架: 1,我有一个后台: 1.1)有一个查询页面,查询页面有很多字段,需要动态地构建SQL。 1.2)我要做好追踪,每一个SQL我都要在日志中打印其执行时长与执行地SQL还有执行结果,同时我要上报prometheus。 1.3)我会经常性地在多个业务表插入大量数据(因为大量数据,所以你要分批插入以防止达到SQL的字符上限或占位符上限)。 2,我有一个数据聚合的服务,它的功能就是数据开发会给各种各样的SQL,然后你就针对各种场景调用不同的SQL就好。同时注意保证可迁移性,我今天可能用Golang,每天我说不定就把这些SQL迁移到python服务上。

这两个我都在用,从设计到使用场景都是完全不一样的,不要因为都是Golang里面流行的,然后又都是可以连接数据库的,就认为是一个东西了。

Comment From: ivila

如果你真的想感受到这两个框架的真正区别之处,我建议可以按照以下的实操学习方式。 首先,学习一些数据库和Golang的database/sql的基础知识: 1,数据库的PrepareStatement与事务隔离 2,golang的database/sql中的DB、Row、Tx、Stmt对象

然后,你去对一张数据表实现CRUD的功能,只实现repo层就好,分别使用: 1,golang原生的database/sql 2,sqlx 3,gorm 通过这种方式你会发现各个框架封装后给你开发带来的效率和便利性 对于第一种,使用原生的database/sql。你会发现你把大量的时间花在了数据库相关的细节上,比如你要亲自调用Preparex以获取一个PrepareStatement,还有每次查询回来后要亲自row.Scan去把一条数据行一个字段一个字段对应地反序列化到一个结构体上,想要插入一条数据就更是噩梦了。同时,你会发现什么时候如果一张表做更改了(比如加字段),你的代码全都要改,并且如果有很多表,那你的代码就会有很多重复的部分,从开发效率和可维护程度来说都是噩梦,不过这种方式执行效率是最高的(也就是你所关心的部分)

对于第二种,使用sqlx。解决了一部分问题,比如很多时候不需要再亲自构建PrepareStatement了,然后也不用一直row.Scan了,但还是有点问题。我加字段的时候,你的Create和Update代码还是要动。这种开发效率和可维护程度还可以(但是实际生产环境肯定不允许,因为日志和各种指标上报都没做),这种方式执行效率次高。

对于第三种,使用gorm。你会发现你代码少了很多,crud也就几行的事情,并且后续加字段也只要给model加字段就好了,不需要做其它调整(实际上gorm还有很多实际生产环境很方便使用的功能),不过这种方式执行效率最差,可问题是,对生产时业务来说代码执行效率的卡点是这里吗?或者相比于网络IO来说这点执行效率是问题吗?

当你操作完以上三部分你会对各个方式有一些直观的感受了,现在再来一个场景,就是你做数据研发,然后你的SQL就是各种超大段SQL直接join各种拼接,使用框架简直是种限制,就算用gorm你也只是不停地Raw,这种时候你可能就改成选sqlx,你想解决的只是一个数据库的反序列化问题而已,用gorm有点高射炮打蚊子了。

其实选型就是一种权衡,考虑收益(可用性,易用性)和代价(性能,框架的限制),不同的场景和个人喜好导致的结果也不同。

Comment From: fineCoderWithLove

您好,您的回答对我很有帮助!

长安少年 @.***

 

------------------ 原始邮件 ------------------ 发件人: "go-gorm/gorm" @.>; 发送时间: 2023年11月15日(星期三) 上午10:09 @.>; @.**@.**>; 主题: Re: [go-gorm/gorm] 我在阅读一篇文章后知道,sqlx在性能上高于gorm,那使用gorm仅仅是为了避免sql注入嘛 (Issue #6689)

如果你真的想感受到这两个框架的真正区别之处,我建议可以按照以下的实操学习方式。 首先,学习一些数据库和Golang的database/sql的基础知识: 1,数据库的PrepareStatement与事务隔离 2,golang的database/sql中的DB、Row、Tx、Stmt对象

然后,你去对一张数据表实现CRUD的功能,只实现repo层就好,分别使用: 1,golang原生的database/sql 2,sqlx 3,gorm 通过这种方式你会发现各个框架封装后给你开发带来的效率和便利性 对于第一种,使用原生的database/sql。你会发现你把大量的时间花在了数据库相关的细节上,比如你要亲自调用Preparex以获取一个PrepareStatement,还有每次查询回来后要亲自row.Scan去把一条数据行一个字段一个字段对应地反序列化到一个结构体上,想要插入一条数据就更是噩梦了。同时,你会发现什么时候如果一张表做更改了(比如加字段),你的代码全都要改,并且如果有很多表,那你的代码就会有很多重复的部分,从开发效率和可维护程度来说都是噩梦,不过这种方式执行效率是最高的(也就是你所关心的部分)

对于第二种,使用sqlx。解决了一部分问题,比如很多时候不需要再亲自构建PrepareStatement了,然后也不用一直row.Scan了,但还是有点问题。我加字段的时候,你的Create和Update代码还是要动。这种开发效率和可维护程度还可以(但是实际生产环境肯定不允许,因为日志和各种指标上报都没做),这种方式执行效率次高。

对于第三种,使用gorm。你会发现你代码少了很多,crud也就几行的事情,并且后续加字段也只要给model加字段就好了,不需要做其它调整(实际上gorm还有很多实际生产环境很方便使用的功能),不过这种方式执行效率最差,可问题是,对生产时业务来说代码执行效率的卡点是这里吗?或者相比于网络IO来说这点执行效率是问题吗?

当你操作完以上三部分你会对各个方式有一些直观的感受了,现在再来一个场景,就是你做数据研发,然后你的SQL就是各种超大段SQL直接join各种拼接,使用框架简直是种限制,就算用gorm你也只是不停地Raw,这种时候你可能就改成选sqlx,你想解决的只是一个数据库的反序列化问题而已,用gorm有点高射炮打蚊子了。

其实选型就是一种权衡,考虑收益(可用性,易用性)和代价(性能,框架的限制),不同的场景和个人喜好导致的结果也不同。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

Comment From: a631807682

@ivila Thank you for helping us answer many community questions