GORM 同时连接 MySQL 和 SQL Server 两种数据库

文章目录

    在实现一个公司内部的质量管理平台 (使用 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式