在实现一个公司内部的质量管理平台 (使用 MySQL 数据库),需要从原有的集采平台 (基于 SQL Server) 中拉取待检验的数据。
为了快速上线,我继续沿用了最顺手的 golang gin & gorm 组合。
但是之前没有试过同时连接两个数据库的用法,而且是两种不同类型的数据库。于是测试了一下。
同时建立两个连接倒是没啥好说的,在原有的 MySQL 配置平级增加一个 MS SQL 的就可以。但是小问题不少。
TLS Handshake failed
建立 SQL Server 连接失败,报错:
TLS Handshake failed: tls: server selected unsupported protocol version 301
在连接字符串后面加上后缀
&encrypt=disable
即可。
MySQL 查询出来的数据为空
在成功同时连接了两个数据库之后,虽然连接正常,但是 MySQL 查询出来的数据结果为空。例如,下面这个返回,count 出的数据总量为 3,但是数据集为空列表。。。
{
"data": [],
"success": true,
"total": 3
}
而这段代码,在没有加入 SQL Server 连接之前是正常的。
可是,即便,我注释掉了所有 SQL Server 相关的代码之后,依然是同样的问题。
我对比了一下 git diff,发现最大的区别是,gorm 的版本由 1.23 升级到了 1.25.
go.mod
- gorm.io/gorm v1.23.8
+ gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde
改成 1.23.8 就正常了。
gorm 的自动升级,是在执行安装 sqlserver 依赖时,自动触发的。
go get gorm.io/driver/sqlserver
于是我手动指定了 sqlserver 依赖的版本为 1.3 (参考 github 上的其他 gorm 1.23 的项目)。然后执行。
> go mod tidy
go: downloading gorm.io/driver/sqlserver v1.3.2
再次编译执行,MySQL 就能正常返回数据了。
GORM Sucks ...
SLOW SQL
写了个简单的 SQL Server 查询测试。没想到触发了一个 SLOW SQL。
SLOW SQL >= 1s
[8774.686ms] [rows:38602] SELECT * FROM "table1" ORDER BY id desc
[12.769ms] [rows:1] SELECT count(*) FROM "table1"
[GIN] GET "/api/get-items"
分页无效。。。
仔细看了一下,原来是 offset 和 limit 参数没有做校验,而 gorm 也没有校验,对于无效值,直接忽略条件。导致全表查询。
改成 limit 10 & offset 0 就正常了。
[51.225ms] [rows:10] SELECT * FROM "table1" ORDER BY id desc OFFSET 0 ROW FETCH NEXT 10 ROWS ONLY
[11.046ms] [rows:1] SELECT count(*) FROM "table1"
每次用 GORM 都心惊胆颤。是时候弃用这货了。
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式